4#include <Tempest/SoundEffect>
21using namespace Tempest;
34 std::shared_ptr<zenkit::DaedalusInstance>
prev;
35 zenkit::DaedalusSymbol&
sym;
41 script.aiProcessPolicy = pp;
53bool GameScript::GlobalOutput::output(
Npc& npc, std::string_view text) {
54 return owner.aiOutput(npc,text,
false);
57bool GameScript::GlobalOutput::outputSvm(
Npc &npc, std::string_view text) {
58 return owner.aiOutputSvm(npc,text,
false);
61bool GameScript::GlobalOutput::outputOv(
Npc &npc, std::string_view text) {
62 return owner.aiOutputSvm(npc,text,
true);
65bool GameScript::GlobalOutput::printScr(
Npc& npc,
int time, std::string_view msg,
int x,
int y, std::string_view font) {
71bool GameScript::GlobalOutput::isFinished() {
83 auto rr = range[perc];
91 :owner(owner), vm(createVm(
Gothic::inst())) {
92 if (vm.global_self() ==
nullptr || vm.global_other() ==
nullptr || vm.global_item() ==
nullptr ||
93 vm.global_victim() ==
nullptr || vm.global_hero() ==
nullptr)
94 throw std::runtime_error(
"Cannot find script symbol SELF, OTHER, ITEM, VICTIM, or HERO! Cannot proceed!");
97 vm.register_exception_handler(zenkit::lenient_vm_exception_handler);
100 aiDefaultPipe.reset(
new GlobalOutput(*
this));
110void GameScript::initCommon() {
111 bindExternal(
"hlp_random", &GameScript::hlp_random);
112 bindExternal(
"hlp_isvalidnpc", &GameScript::hlp_isvalidnpc);
113 bindExternal(
"hlp_isvaliditem", &GameScript::hlp_isvaliditem);
114 bindExternal(
"hlp_isitem", &GameScript::hlp_isitem);
115 bindExternal(
"hlp_getnpc", &GameScript::hlp_getnpc);
116 bindExternal(
"hlp_getinstanceid", &GameScript::hlp_getinstanceid);
118 bindExternal(
"wld_insertnpc", &GameScript::wld_insertnpc);
119 bindExternal(
"wld_removenpc", &GameScript::wld_removenpc);
120 bindExternal(
"wld_insertitem", &GameScript::wld_insertitem);
121 bindExternal(
"wld_settime", &GameScript::wld_settime);
122 bindExternal(
"wld_getday", &GameScript::wld_getday);
123 bindExternal(
"wld_playeffect", &GameScript::wld_playeffect);
124 bindExternal(
"wld_stopeffect", &GameScript::wld_stopeffect);
125 bindExternal(
"wld_getplayerportalguild", &GameScript::wld_getplayerportalguild);
126 bindExternal(
"wld_getformerplayerportalguild", &GameScript::wld_getformerplayerportalguild);
127 bindExternal(
"wld_setguildattitude", &GameScript::wld_setguildattitude);
128 bindExternal(
"wld_getguildattitude", &GameScript::wld_getguildattitude);
129 bindExternal(
"wld_exchangeguildattitudes", &GameScript::wld_exchangeguildattitudes);
130 bindExternal(
"wld_istime", &GameScript::wld_istime);
131 bindExternal(
"wld_isfpavailable", &GameScript::wld_isfpavailable);
132 bindExternal(
"wld_isnextfpavailable", &GameScript::wld_isnextfpavailable);
133 bindExternal(
"wld_ismobavailable", &GameScript::wld_ismobavailable);
134 bindExternal(
"wld_setmobroutine", &GameScript::wld_setmobroutine);
135 bindExternal(
"wld_getmobstate", &GameScript::wld_getmobstate);
136 bindExternal(
"wld_assignroomtoguild", &GameScript::wld_assignroomtoguild);
137 bindExternal(
"wld_detectnpc", &GameScript::wld_detectnpc);
138 bindExternal(
"wld_detectnpcex", &GameScript::wld_detectnpcex);
139 bindExternal(
"wld_detectitem", &GameScript::wld_detectitem);
140 bindExternal(
"wld_spawnnpcrange", &GameScript::wld_spawnnpcrange);
141 bindExternal(
"wld_sendtrigger", &GameScript::wld_sendtrigger);
142 bindExternal(
"wld_senduntrigger", &GameScript::wld_senduntrigger);
143 bindExternal(
"wld_israining", &GameScript::wld_israining);
145 bindExternal(
"mdl_setvisual", &GameScript::mdl_setvisual);
146 bindExternal(
"mdl_setvisualbody", &GameScript::mdl_setvisualbody);
147 bindExternal(
"mdl_setmodelfatness", &GameScript::mdl_setmodelfatness);
148 bindExternal(
"mdl_applyoverlaymds", &GameScript::mdl_applyoverlaymds);
149 bindExternal(
"mdl_applyoverlaymdstimed", &GameScript::mdl_applyoverlaymdstimed);
150 bindExternal(
"mdl_removeoverlaymds", &GameScript::mdl_removeoverlaymds);
151 bindExternal(
"mdl_setmodelscale", &GameScript::mdl_setmodelscale);
152 bindExternal(
"mdl_startfaceani", &GameScript::mdl_startfaceani);
153 bindExternal(
"mdl_applyrandomani", &GameScript::mdl_applyrandomani);
154 bindExternal(
"mdl_applyrandomanifreq", &GameScript::mdl_applyrandomanifreq);
155 bindExternal(
"mdl_applyrandomfaceani", &GameScript::mdl_applyrandomfaceani);
157 bindExternal(
"npc_settofightmode", &GameScript::npc_settofightmode);
158 bindExternal(
"npc_settofistmode", &GameScript::npc_settofistmode);
159 bindExternal(
"npc_isinstate", &GameScript::npc_isinstate);
160 bindExternal(
"npc_isinroutine", &GameScript::npc_isinroutine);
161 bindExternal(
"npc_wasinstate", &GameScript::npc_wasinstate);
162 bindExternal(
"npc_getdisttowp", &GameScript::npc_getdisttowp);
163 bindExternal(
"npc_exchangeroutine", &GameScript::npc_exchangeroutine);
164 bindExternal(
"npc_isdead", &GameScript::npc_isdead);
165 bindExternal(
"npc_knowsinfo", &GameScript::npc_knowsinfo);
166 bindExternal(
"npc_settalentskill", &GameScript::npc_settalentskill);
167 bindExternal(
"npc_gettalentskill", &GameScript::npc_gettalentskill);
168 bindExternal(
"npc_settalentvalue", &GameScript::npc_settalentvalue);
169 bindExternal(
"npc_gettalentvalue", &GameScript::npc_gettalentvalue);
170 bindExternal(
"npc_setrefusetalk", &GameScript::npc_setrefusetalk);
171 bindExternal(
"npc_refusetalk", &GameScript::npc_refusetalk);
172 bindExternal(
"npc_hasitems", &GameScript::npc_hasitems);
173 bindExternal(
"npc_hasspell", &GameScript::npc_hasspell);
174 bindExternal(
"npc_getinvitem", &GameScript::npc_getinvitem);
175 bindExternal(
"npc_getinvitembyslot", &GameScript::npc_getinvitembyslot);
176 bindExternal(
"npc_removeinvitem", &GameScript::npc_removeinvitem);
177 bindExternal(
"npc_removeinvitems", &GameScript::npc_removeinvitems);
178 bindExternal(
"npc_getbodystate", &GameScript::npc_getbodystate);
179 bindExternal(
"npc_getlookattarget", &GameScript::npc_getlookattarget);
180 bindExternal(
"npc_getdisttonpc", &GameScript::npc_getdisttonpc);
181 bindExternal(
"npc_hasequippedarmor", &GameScript::npc_hasequippedarmor);
182 bindExternal(
"npc_setperctime", &GameScript::npc_setperctime);
183 bindExternal(
"npc_percenable", &GameScript::npc_percenable);
184 bindExternal(
"npc_percdisable", &GameScript::npc_percdisable);
185 bindExternal(
"npc_getnearestwp", &GameScript::npc_getnearestwp);
186 bindExternal(
"npc_getnextwp", &GameScript::npc_getnextwp);
187 bindExternal(
"npc_clearaiqueue", &GameScript::npc_clearaiqueue);
188 bindExternal(
"npc_isplayer", &GameScript::npc_isplayer);
189 bindExternal(
"npc_getstatetime", &GameScript::npc_getstatetime);
190 bindExternal(
"npc_setstatetime", &GameScript::npc_setstatetime);
191 bindExternal(
"npc_changeattribute", &GameScript::npc_changeattribute);
192 bindExternal(
"npc_isonfp", &GameScript::npc_isonfp);
193 bindExternal(
"npc_getheighttonpc", &GameScript::npc_getheighttonpc);
194 bindExternal(
"npc_getequippedmeleeweapon", &GameScript::npc_getequippedmeleeweapon);
195 bindExternal(
"npc_getequippedrangedweapon", &GameScript::npc_getequippedrangedweapon);
196 bindExternal(
"npc_getequippedarmor", &GameScript::npc_getequippedarmor);
197 bindExternal(
"npc_canseenpc", &GameScript::npc_canseenpc);
198 bindExternal(
"npc_canseenpcfreelos", &GameScript::npc_canseenpcfreelos);
199 bindExternal(
"npc_canseeitem", &GameScript::npc_canseeitem);
200 bindExternal(
"npc_hasequippedweapon", &GameScript::npc_hasequippedweapon);
201 bindExternal(
"npc_hasequippedmeleeweapon", &GameScript::npc_hasequippedmeleeweapon);
202 bindExternal(
"npc_hasequippedrangedweapon", &GameScript::npc_hasequippedrangedweapon);
203 bindExternal(
"npc_getactivespell", &GameScript::npc_getactivespell);
204 bindExternal(
"npc_getactivespellisscroll", &GameScript::npc_getactivespellisscroll);
205 bindExternal(
"npc_getactivespellcat", &GameScript::npc_getactivespellcat);
206 bindExternal(
"npc_setactivespellinfo", &GameScript::npc_setactivespellinfo);
207 bindExternal(
"npc_getactivespelllevel", &GameScript::npc_getactivespelllevel);
208 bindExternal(
"npc_isinfightmode", &GameScript::npc_isinfightmode);
209 bindExternal(
"npc_settarget", &GameScript::npc_settarget);
210 bindExternal(
"npc_gettarget", &GameScript::npc_gettarget);
211 bindExternal(
"npc_getnexttarget", &GameScript::npc_getnexttarget);
212 bindExternal(
"npc_sendpassiveperc", &GameScript::npc_sendpassiveperc);
213 bindExternal(
"npc_sendsingleperc", &GameScript::npc_sendsingleperc);
214 bindExternal(
"npc_checkinfo", &GameScript::npc_checkinfo);
215 bindExternal(
"npc_getportalguild", &GameScript::npc_getportalguild);
216 bindExternal(
"npc_isinplayersroom", &GameScript::npc_isinplayersroom);
217 bindExternal(
"npc_getreadiedweapon", &GameScript::npc_getreadiedweapon);
218 bindExternal(
"npc_hasreadiedweapon", &GameScript::npc_hasreadiedweapon);
219 bindExternal(
"npc_hasreadiedmeleeweapon", &GameScript::npc_hasreadiedmeleeweapon);
220 bindExternal(
"npc_hasreadiedrangedweapon", &GameScript::npc_hasreadiedrangedweapon);
221 bindExternal(
"npc_hasrangedweaponwithammo", &GameScript::npc_hasrangedweaponwithammo);
222 bindExternal(
"npc_isdrawingspell", &GameScript::npc_isdrawingspell);
223 bindExternal(
"npc_isdrawingweapon", &GameScript::npc_isdrawingweapon);
224 bindExternal(
"npc_perceiveall", &GameScript::npc_perceiveall);
225 bindExternal(
"npc_stopani", &GameScript::npc_stopani);
226 bindExternal(
"npc_settrueguild", &GameScript::npc_settrueguild);
227 bindExternal(
"npc_gettrueguild", &GameScript::npc_gettrueguild);
228 bindExternal(
"npc_clearinventory", &GameScript::npc_clearinventory);
229 bindExternal(
"npc_getattitude", &GameScript::npc_getattitude);
230 bindExternal(
"npc_getpermattitude", &GameScript::npc_getpermattitude);
231 bindExternal(
"npc_setattitude", &GameScript::npc_setattitude);
232 bindExternal(
"npc_settempattitude", &GameScript::npc_settempattitude);
233 bindExternal(
"npc_hasbodyflag", &GameScript::npc_hasbodyflag);
234 bindExternal(
"npc_getlasthitspellid", &GameScript::npc_getlasthitspellid);
235 bindExternal(
"npc_getlasthitspellcat", &GameScript::npc_getlasthitspellcat);
236 bindExternal(
"npc_playani", &GameScript::npc_playani);
237 bindExternal(
"npc_isdetectedmobownedbynpc", &GameScript::npc_isdetectedmobownedbynpc);
238 bindExternal(
"npc_getdetectedmob", &GameScript::npc_getdetectedmob);
239 bindExternal(
"npc_isdetectedmobownedbyguild", &GameScript::npc_isdetectedmobownedbyguild);
240 bindExternal(
"npc_ownedbynpc", &GameScript::npc_ownedbynpc);
241 bindExternal(
"npc_canseesource", &GameScript::npc_canseesource);
242 bindExternal(
"npc_isincutscene", &GameScript::npc_isincutscene);
243 bindExternal(
"npc_getdisttoitem", &GameScript::npc_getdisttoitem);
244 bindExternal(
"npc_getheighttoitem", &GameScript::npc_getheighttoitem);
245 bindExternal(
"npc_getdisttoplayer", &GameScript::npc_getdisttoplayer);
247 bindExternal(
"ai_output", &GameScript::ai_output);
248 bindExternal(
"ai_stopprocessinfos", &GameScript::ai_stopprocessinfos);
249 bindExternal(
"ai_processinfos", &GameScript::ai_processinfos);
250 bindExternal(
"ai_standup", &GameScript::ai_standup);
251 bindExternal(
"ai_standupquick", &GameScript::ai_standupquick);
252 bindExternal(
"ai_continueroutine", &GameScript::ai_continueroutine);
253 bindExternal(
"ai_stoplookat", &GameScript::ai_stoplookat);
254 bindExternal(
"ai_lookat", &GameScript::ai_lookat);
255 bindExternal(
"ai_lookatnpc", &GameScript::ai_lookatnpc);
256 bindExternal(
"ai_removeweapon", &GameScript::ai_removeweapon);
257 bindExternal(
"ai_unreadyspell", &GameScript::ai_unreadyspell);
258 bindExternal(
"ai_turnaway", &GameScript::ai_turnaway);
259 bindExternal(
"ai_turntonpc", &GameScript::ai_turntonpc);
260 bindExternal(
"ai_whirlaround", &GameScript::ai_whirlaround);
261 bindExternal(
"ai_outputsvm", &GameScript::ai_outputsvm);
262 bindExternal(
"ai_outputsvm_overlay", &GameScript::ai_outputsvm_overlay);
263 bindExternal(
"ai_startstate", &GameScript::ai_startstate);
264 bindExternal(
"ai_playani", &GameScript::ai_playani);
265 bindExternal(
"ai_setwalkmode", &GameScript::ai_setwalkmode);
266 bindExternal(
"ai_wait", &GameScript::ai_wait);
267 bindExternal(
"ai_waitms", &GameScript::ai_waitms);
268 bindExternal(
"ai_aligntowp", &GameScript::ai_aligntowp);
269 bindExternal(
"ai_gotowp", &GameScript::ai_gotowp);
270 bindExternal(
"ai_gotofp", &GameScript::ai_gotofp);
271 bindExternal(
"ai_playanibs", &GameScript::ai_playanibs);
272 bindExternal(
"ai_equiparmor", &GameScript::ai_equiparmor);
273 bindExternal(
"ai_equipbestarmor", &GameScript::ai_equipbestarmor);
274 bindExternal(
"ai_equipbestmeleeweapon", &GameScript::ai_equipbestmeleeweapon);
275 bindExternal(
"ai_equipbestrangedweapon", &GameScript::ai_equipbestrangedweapon);
276 bindExternal(
"ai_usemob", &GameScript::ai_usemob);
277 bindExternal(
"ai_teleport", &GameScript::ai_teleport);
278 bindExternal(
"ai_stoppointat", &GameScript::ai_stoppointat);
279 bindExternal(
"ai_drawweapon", &GameScript::ai_drawweapon);
280 bindExternal(
"ai_readymeleeweapon", &GameScript::ai_readymeleeweapon);
281 bindExternal(
"ai_readyrangedweapon", &GameScript::ai_readyrangedweapon);
282 bindExternal(
"ai_readyspell", &GameScript::ai_readyspell);
283 bindExternal(
"ai_attack", &GameScript::ai_attack);
284 bindExternal(
"ai_flee", &GameScript::ai_flee);
285 bindExternal(
"ai_dodge", &GameScript::ai_dodge);
286 bindExternal(
"ai_unequipweapons", &GameScript::ai_unequipweapons);
287 bindExternal(
"ai_unequiparmor", &GameScript::ai_unequiparmor);
288 bindExternal(
"ai_gotonpc", &GameScript::ai_gotonpc);
289 bindExternal(
"ai_gotonextfp", &GameScript::ai_gotonextfp);
290 bindExternal(
"ai_aligntofp", &GameScript::ai_aligntofp);
291 bindExternal(
"ai_useitem", &GameScript::ai_useitem);
292 bindExternal(
"ai_useitemtostate", &GameScript::ai_useitemtostate);
293 bindExternal(
"ai_setnpcstostate", &GameScript::ai_setnpcstostate);
294 bindExternal(
"ai_finishingmove", &GameScript::ai_finishingmove);
295 bindExternal(
"ai_takeitem", &GameScript::ai_takeitem);
296 bindExternal(
"ai_gotoitem", &GameScript::ai_gotoitem);
297 bindExternal(
"ai_pointat", &GameScript::ai_pointat);
298 bindExternal(
"ai_pointatnpc", &GameScript::ai_pointatnpc);
300 bindExternal(
"mob_hasitems", &GameScript::mob_hasitems);
301 bindExternal(
"ai_printscreen", &GameScript::ai_printscreen);
303 bindExternal(
"ta_min", &GameScript::ta_min);
305 bindExternal(
"log_createtopic", &GameScript::log_createtopic);
306 bindExternal(
"log_settopicstatus", &GameScript::log_settopicstatus);
307 bindExternal(
"log_addentry", &GameScript::log_addentry);
309 bindExternal(
"equipitem", &GameScript::equipitem);
310 bindExternal(
"createinvitem", &GameScript::createinvitem);
311 bindExternal(
"createinvitems", &GameScript::createinvitems);
313 bindExternal(
"perc_setrange", &GameScript::perc_setrange);
315 bindExternal(
"info_addchoice", &GameScript::info_addchoice);
316 bindExternal(
"info_clearchoices", &GameScript::info_clearchoices);
317 bindExternal(
"infomanager_hasfinished", &GameScript::infomanager_hasfinished);
319 bindExternal(
"snd_play", &GameScript::snd_play);
320 bindExternal(
"snd_play3d", &GameScript::snd_play3d);
322 bindExternal(
"game_initgerman", &GameScript::game_initgerman);
323 bindExternal(
"game_initenglish", &GameScript::game_initenglish);
325 bindExternal(
"exitsession", &GameScript::exitsession);
329 spells = std::make_unique<SpellDefinitions>(vm);
330 svm = std::make_unique<SvmDefinitions>(vm);
332 cFocusNorm = findFocus(
"Focus_Normal");
333 cFocusMelee = findFocus(
"Focus_Melee");
334 cFocusRange = findFocus(
"Focus_Ranged");
335 cFocusMage = findFocus(
"Focus_Magic");
343 spellFxInstanceNames = vm.find_symbol_by_name(
"spellFxInstanceNames");
344 spellFxAniLetters = vm.find_symbol_by_name(
"spellFxAniLetters");
346 if(spellFxInstanceNames==
nullptr || spellFxAniLetters==
nullptr) {
347 throw std::runtime_error(
"spellFxInstanceNames and/or spellFxAniLetters not found");
351 auto* currency = vm.find_symbol_by_name(
"TRADE_CURRENCY_INSTANCE");
352 itMi_Gold = currency!=
nullptr ? vm.find_symbol_by_name(currency->get_string()) :
nullptr;
353 if(itMi_Gold!=
nullptr){
354 auto item = vm.init_instance<zenkit::IItem>(itMi_Gold);
355 goldTxt = item->name;
357 auto* tradeMul = vm.find_symbol_by_name(
"TRADE_VALUE_MULTIPLIER");
358 tradeValMult = tradeMul !=
nullptr ? tradeMul->get_float() : 1.0f;
360 auto* vtime = vm.find_symbol_by_name(
"VIEW_TIME_PER_CHAR");
361 viewTimePerChar = vtime !=
nullptr ? vtime->get_float() : 550.f;
362 if(viewTimePerChar<=0.f)
363 viewTimePerChar = 550.f;
365 ItKE_lockpick = vm.find_symbol_by_name(
"ItKE_lockpick");
366 B_RefreshAtInsert = vm.find_symbol_by_name(
"B_RefreshAtInsert");
368 itMi_Gold = vm.find_symbol_by_name(
"ItMiNugget");
369 if(itMi_Gold!=
nullptr) {
370 auto item = vm.init_instance<zenkit::IItem>(itMi_Gold);
371 goldTxt = item->name;
375 viewTimePerChar = 550.f;
376 ItKE_lockpick = vm.find_symbol_by_name(
"itkelockpick");
379 if(
auto v = vm.find_symbol_by_name(
"DAM_CRITICAL_MULTIPLIER")) {
380 damCriticalMultiplier = v->get_int();
383 auto* gilMax = vm.find_symbol_by_name(
"GIL_MAX");
384 gilCount = gilMax!=
nullptr ? size_t(gilMax->get_int()) : 0;
386 auto* tblSz = vm.find_symbol_by_name(
"TAB_ANZAHL");
387 gilTblSize = tblSz!=
nullptr ? size_t(std::sqrt(tblSz->get_int())) : 0;
388 gilAttitudes.resize(gilCount*gilCount,
ATT_HOSTILE);
389 wld_exchangeguildattitudes(
"GIL_ATTITUDES");
391 auto id = vm.find_symbol_by_name(
"Gil_Values");
393 cGuildVal = vm.init_instance<zenkit::IGuildValues>(id);
395 cGuildVal->water_depth_knee [i]=cGuildVal->water_depth_knee [
Guild::GIL_HUMAN];
396 cGuildVal->water_depth_chest [i]=cGuildVal->water_depth_chest [
Guild::GIL_HUMAN];
405 cGuildVal->disable_autoroll [i]=cGuildVal->disable_autoroll [
Guild::GIL_HUMAN];
407 cGuildVal->climb_heading_angle[i]=cGuildVal->climb_heading_angle[
Guild::GIL_HUMAN];
408 cGuildVal->climb_horiz_angle [i]=cGuildVal->climb_horiz_angle [
Guild::GIL_HUMAN];
409 cGuildVal->climb_ground_angle [i]=cGuildVal->climb_ground_angle [
Guild::GIL_HUMAN];
410 cGuildVal->fight_range_base [i]=cGuildVal->fight_range_base [
Guild::GIL_HUMAN];
411 cGuildVal->fight_range_fist [i]=cGuildVal->fight_range_fist [
Guild::GIL_HUMAN];
413 cGuildVal->fight_range_1hs [i]=cGuildVal->fight_range_1hs [
Guild::GIL_HUMAN];
414 cGuildVal->fight_range_1ha [i]=cGuildVal->fight_range_1ha [
Guild::GIL_HUMAN];
415 cGuildVal->fight_range_2hs [i]=cGuildVal->fight_range_2hs [
Guild::GIL_HUMAN];
416 cGuildVal->fight_range_2ha [i]=cGuildVal->fight_range_2ha [
Guild::GIL_HUMAN];
417 cGuildVal->falldown_height [i]=cGuildVal->falldown_height [
Guild::GIL_HUMAN];
418 cGuildVal->falldown_damage [i]=cGuildVal->falldown_damage [
Guild::GIL_HUMAN];
420 cGuildVal->blood_max_distance [i]=cGuildVal->blood_max_distance [
Guild::GIL_HUMAN];
433void GameScript::initSettings() {
446 vm.enumerate_instances_by_class_name(
"C_INFO", [
this](zenkit::DaedalusSymbol& sym){
447 dialogsInfo.push_back(vm.init_instance<zenkit::IInfo>(&sym));
451void GameScript::loadDialogOU() {
454 const std::string prefix = std::string(
Gothic::inst().defaultOutputUnits());
455 const std::array<std::string,2> names = {prefix +
".BIN", prefix +
".DAT"};
458 : zenkit::GameVersion::GOTHIC_2;
460 for(
auto& OU:names) {
462 std::unique_ptr<zenkit::Read> read;
464 dialogs = std::move(*zen->read_object<zenkit::CutsceneLibrary>(version));
468 const size_t segment = OU.find_last_of(
"\\/");
470 std::unique_ptr<zenkit::Read> read;
472 dialogs = std::move(*zen->read_object<zenkit::CutsceneLibrary>(version));
476 char16_t str16[256] = {};
477 for(
size_t i=0; OU[i] && i<255; ++i)
478 str16[i] =
char16_t(OU[i]);
488 auto buf = zenkit::Read::from(full);
491 auto zen = zenkit::ReadArchive::from(buf.get());
495 dialogs = std::move(*zen->read_object<zenkit::CutsceneLibrary>(version));
502 Log::e(
"none of Zen-files for OU could be loaded");
506 auto sym = vm.find_symbol_by_index(uint32_t(
instance));
509 Tempest::Log::e(
"Cannot initialize NPC ",
instance,
": Symbol not found.");
513 vm.init_instance(npc, sym);
515 if(npc->daily_routine!=0) {
516 ScopeVar self(*vm.global_self(), npc);
517 auto* daily_routine = vm.find_symbol_by_index(uint32_t(npc->daily_routine));
519 if(daily_routine !=
nullptr) {
520 vm.call_function(daily_routine);
526 auto sym = vm.find_symbol_by_index(uint32_t(
instance));
529 Tempest::Log::e(
"Cannot initialize item ",
instance,
": Symbol not found.");
533 vm.init_instance(item, sym);
538 fout.
write(uint32_t(dlgKnownInfos.size()));
539 for(
auto& i:dlgKnownInfos)
540 fout.
write(uint32_t(i.first),uint32_t(i.second));
542 fout.
write(gilAttitudes);
549 for(
size_t i=0;i<sz;++i){
552 dlgKnownInfos.insert(std::make_pair(f,s));
555 fin.
read(gilAttitudes);
559 auto& dat = vm.symbols();
560 fout.
write(uint32_t(dat.size()));
561 for(
unsigned i = 0; i < dat.size(); ++i){
562 auto* sym = vm.find_symbol_by_index(i);
571 for(
size_t i=0;i<sz;++i){
572 auto t = uint32_t(zenkit::DaedalusDataType::VOID);
574 switch(zenkit::DaedalusDataType(t)) {
575 case zenkit::DaedalusDataType::INT:{
583 for(
unsigned j = 0; j < size; ++j) {
585 if (s !=
nullptr && !s->is_member() && !s->is_const()) {
586 s->set_int(v, uint16_t(j));
592 case zenkit::DaedalusDataType::FLOAT:{
600 for (
unsigned j = 0; j < size; ++j) {
602 if (s !=
nullptr && !s->is_member() && !s->is_const()) {
603 s->set_float(v, uint16_t(j));
609 case zenkit::DaedalusDataType::STRING:{
617 for (
unsigned j = 0; j < size; ++j) {
619 if (s !=
nullptr && !s->is_member() && !s->is_const()) {
620 s->set_string(v, uint16_t(j));
626 case zenkit::DaedalusDataType::INSTANCE:{
637 s->set_instance(npc ? npc->
handlePtr() :
nullptr);
639 else if(dataClass==2) {
641 s->set_instance(itm !=
nullptr ? itm->handlePtr() :
nullptr);
643 else if(dataClass==3) {
647 auto itm = npc->
getItem(itmClass);
648 s->set_instance(itm ? itm->handlePtr() :
nullptr);
672 vm.call_function(
"initPerceptions");
680 for(uint32_t i=0;i<vm.symbols().size();++i){
681 auto* s = vm.find_symbol_by_index(i);
682 if(s->is_instance_of<zenkit::INpc>() || s->is_instance_of<zenkit::IItem>()){
683 s->set_instance(
nullptr);
692void GameScript::saveSym(
Serialize &fout, zenkit::DaedalusSymbol& i) {
695 case zenkit::DaedalusDataType::INT:
696 if(i.count()>0 && !i.is_member() && !i.is_const()){
697 fout.
write(i.type(), i.name(), i.count());
699 for (
unsigned j = 0; j < i.count(); ++j)
700 fout.
write(i.get_int(uint16_t(j)));
704 case zenkit::DaedalusDataType::FLOAT:
705 if(i.count()>0 && !i.is_member() && !i.is_const()){
706 fout.
write(i.type(), i.name(), i.count());
708 for (
unsigned j = 0; j < i.count(); ++j)
709 fout.
write(i.get_float(uint16_t(j)));
713 case zenkit::DaedalusDataType::STRING:
714 if(i.count()>0 && !i.is_member() && !i.is_const()){
715 fout.
write(i.type(), i.name(), i.count());
717 for (
unsigned j = 0; j < i.count(); ++j)
718 fout.
write(i.get_string(uint16_t(j)));
722 case zenkit::DaedalusDataType::INSTANCE:
723 fout.
write(i.type());
725 if(i.is_instance_of<zenkit::INpc>()){
726 auto hnpc =
reinterpret_cast<const zenkit::INpc*
>(i.get_instance().get());
727 auto npc =
reinterpret_cast<const Npc*
>(hnpc==
nullptr ? nullptr : hnpc->user_ptr);
730 else if(i.is_instance_of<zenkit::IItem>()){
731 auto item =
reinterpret_cast<const zenkit::IItem*
>(i.get_instance().get());
732 uint32_t
id = w.itmId(item);
733 if(
id!=uint32_t(-1) || item==
nullptr) {
734 fout.
write(uint8_t(2),i.name(),id);
736 uint32_t idNpc = uint32_t(-1);
737 for(uint32_t r=0; r<w.npcCount(); ++r) {
738 auto& n = *w.npcById(r);
739 if(n.itemCount(item->symbol_index())>0) {
741 fout.
write(uint8_t(3),i.name(),idNpc,uint32_t(item->symbol_index()));
745 if(idNpc==uint32_t(-1))
746 fout.
write(uint8_t(2),i.name(),uint32_t(-1));
749 else if(i.is_instance_of<zenkit::IFocus>() ||
750 i.is_instance_of<zenkit::IGuildValues>() ||
751 i.is_instance_of<zenkit::IInfo>()) {
752 fout.
write(uint8_t(0));
755 fout.
write(uint8_t(0));
761 fout.
write(uint32_t(zenkit::DaedalusDataType::VOID));
768 for(
int r = 0; r<=800; r+=20) {
769 for(
float ang = 0; ang<360; ang+=30.f) {
770 float a = float((ang+angle0)*M_PI/180.0);
771 float d = float(r)+distBias;
772 auto p = pos0+Vec3(std::cos(a)*d, 0, std::sin(a)*d);
774 auto ray = dyn.ray(p+Vec3(0,100,0), p+Vec3(0,-1000,0));
789 dma->eventPlayAni(ani);
793 return *owner.
world();
797 return *owner.
world();
800zenkit::IFocus GameScript::findFocus(std::string_view name) {
801 auto id = vm.find_symbol_by_name(name);
805 return *vm.init_instance<zenkit::IFocus>(id);
807 catch(
const zenkit::DaedalusScriptError&) {
812void GameScript::storeItem(
Item *itm) {
813 auto* s = vm.global_item();
817 s->set_instance(
nullptr);
822 return vm.find_symbol_by_name(s);
826 return vm.find_symbol_by_index(uint32_t(s));
830 auto sym = vm.find_symbol_by_name(name);
831 return sym ==
nullptr ? size_t(-1) : sym->index();
835 return vm.symbols().size();
839 auto it = aiStates.find(
id.ptr);
840 if(it!=aiStates.end())
842 auto ins = aiStates.emplace(
id.ptr,
AiState(*
this,
id.ptr));
843 return ins.first->second;
847 auto& tag = spellFxInstanceNames->get_string(uint16_t(splId));
848 return spells->find(tag);
852 auto& tag = spellFxInstanceNames->get_string(uint16_t(splId));
858 std::shared_ptr<zenkit::INpc> hnpc,
859 const std::vector<uint32_t>& except,
861 ScopeVar self (*vm.global_self(), hnpc);
862 ScopeVar other(*vm.global_other(), player);
863 std::vector<zenkit::IInfo*> hDialog;
864 for(
auto& info : dialogsInfo) {
865 if(info->npc==
static_cast<int>(hnpc->symbol_index())) {
866 hDialog.push_back(info.get());
870 std::vector<DlgChoice> choice;
871 for(
int important=includeImp ? 1 : 0;important>=0;--important){
872 for(
auto& i:hDialog) {
873 const zenkit::IInfo& info = *i;
874 if(info.important!=important)
876 bool npcKnowsInfo = doesNpcKnowInfo(*player,vm.find_symbol_by_instance(info)->index());
877 if(npcKnowsInfo && !info.permanent)
880 if(info.important && info.permanent){
883 if(
static_cast<int>(i)==info.information){
893 auto* conditionSymbol = vm.find_symbol_by_index(uint32_t(info.condition));
894 if (conditionSymbol !=
nullptr) {
895 valid = vm.call_function<
int>(conditionSymbol) != 0;
902 ch.
title = info.description;
903 ch.
scriptFn = uint32_t(info.information);
907 choice.emplace_back(std::move(ch));
921 const zenkit::IInfo& info = *dlg.
handle;
922 std::vector<GameScript::DlgChoice> ret;
927 for(
size_t i=0;i<info.choices.size();++i){
928 auto& sub = info.choices[i];
931 ch.
scriptFn = uint32_t(sub.function);
946 zenkit::IInfo& info = *dlg.
handle;
950 auto& pl = player.
handle();
952 if(info.information==
int(dlg.
scriptFn)) {
953 setNpcInfoKnown(pl,info);
955 for(
size_t i=0;i<info.choices.size();){
956 if(info.choices[i].function==
int(dlg.
scriptFn))
957 info.choices.erase(info.choices.begin()+
int(i));
else
961 vm.call_function(vm.find_symbol_by_index(dlg.
scriptFn));
965 auto id = vm.find_symbol_by_name(
"G_CanNotUse");
970 vm.call_function<
void>(id, npc.
isPlayer(), atr, nValue);
974 auto id = vm.find_symbol_by_name(
"G_CanNotCast");
979 vm.call_function<
void>(id, npc.
isPlayer(), itM, plM);
983 auto id = vm.find_symbol_by_name(
"player_trade_not_enough_gold");
987 vm.call_function<
void>(id);
991 auto id = vm.find_symbol_by_name(
"player_mob_missing_item");
998 vm.call_function<
void>(id);
1002 auto id = vm.find_symbol_by_name(
"player_mob_missing_key");
1009 vm.call_function<
void>(id);
1013 auto id = vm.find_symbol_by_name(
"player_mob_another_is_using");
1020 vm.call_function<
void>(id);
1024 auto id = vm.find_symbol_by_name(
"player_mob_missing_key_or_lockpick");
1031 vm.call_function<
void>(id);
1035 auto id = vm.find_symbol_by_name(
"player_mob_missing_lockpick");
1042 vm.call_function<
void>(id);
1046 auto id = vm.find_symbol_by_name(
"player_mob_too_far_away");
1052 vm.call_function<
void>(id);
1055void GameScript::invokeState(
const std::shared_ptr<zenkit::INpc>& hnpc,
const std::shared_ptr<zenkit::INpc>& oth,
const char *name) {
1056 auto id = vm.find_symbol_by_name(name);
1060 ScopeVar self (*vm.global_self(), hnpc);
1061 ScopeVar other(*vm.global_other(), oth);
1062 vm.call_function<
void>(id);
1076 if(oth==
nullptr || !oth->
isPlayer()) {
1077 Log::e(
"unxepected perc acton");
1084 ScopeVar other (*vm.global_other(), oth !=
nullptr ? oth->
handlePtr() :
nullptr);
1085 ScopeVar victim(*vm.global_victim(), vic !=
nullptr ? vic->
handlePtr() :
nullptr);
1087 auto* sym = vm.find_symbol_by_index(uint32_t(fn.
ptr));
1089 if(sym!=
nullptr && sym->rtype() == zenkit::DaedalusDataType::INT) {
1090 ret = vm.call_function<
int>(sym);
1092 else if(sym!=
nullptr) {
1093 vm.call_function<
void>(sym);
1097 if(vm.global_other()->is_instance_of<zenkit::INpc>()){
1098 auto oth2 =
reinterpret_cast<zenkit::INpc*
>(vm.global_other()->get_instance().get());
1099 if(oth!=
nullptr && oth2!=&oth->
handle()) {
1100 Npc* other = findNpc(oth2);
1108 if(fn==
size_t(-1) || fn == 0)
1110 auto functionSymbol = vm.find_symbol_by_index(uint32_t(fn.
ptr));
1112 if (functionSymbol ==
nullptr)
1116 vm.call_function<
void>(functionSymbol);
1120 auto fn = vm.find_symbol_by_name(
"Spell_ProcessMana");
1125 ScopeVar other(*vm.global_other(), target !=
nullptr ? target->
handlePtr() :
nullptr);
1127 return vm.call_function<
int>(fn,mana);
1131 auto fn = vm.find_symbol_by_name(
"Spell_ProcessMana_Release");
1136 ScopeVar other(*vm.global_other(), target !=
nullptr ? target->
handlePtr() :
nullptr);
1138 return vm.call_function<
int>(fn,mana);
1142 auto& tag = spellFxInstanceNames->get_string(uint16_t(it.
spellId()));
1144 auto fn = vm.find_symbol_by_name(name);
1149 int32_t splLevel = 0;
1151 ScopeVar other(*vm.global_other(), target !=
nullptr ? target->
handlePtr() :
nullptr);
1153 if(fn->count()==1) {
1155 vm.call_function<
void>(fn, splLevel);
1157 vm.call_function<
void>(fn);
1161 Log::d(
"unable to call spell-script: \"",name,
"\'");
1166 auto fn = vm.find_symbol_by_name(func);
1172 return vm.call_function<
int>(fn);
1176 auto fn = vm.find_symbol_by_name(
"G_PickLock");
1180 vm.call_function<
void>(fn, bSuccess, bBrokenOpen);
1184 if(B_RefreshAtInsert==
nullptr || owner.
version().game!=2)
1187 vm.call_function<
void>(B_RefreshAtInsert);
1198 auto fn = vm.find_symbol_by_name(
"C_CanNpcCollideWithSpell");
1204 return CollideMask(vm.call_function<
int>(fn, spellId));
1211 if(map==
size_t(-1) || pl.
itemCount(map)<1)
1214 if(map==
size_t(-1) || pl.
itemCount(map)<1)
1223 auto fn = vm.find_symbol_by_name(
"player_hotkey_screen_map");
1231 int map = vm.call_function<
int>(fn);
1242 auto fn = vm.find_symbol_by_name(
"player_hotkey_lame_potion");
1247 vm.call_function<
void>(fn);
1255 auto fn = vm.find_symbol_by_name(
"player_hotkey_lame_heal");
1260 vm.call_function<
void>(fn);
1264 if(spellFxAniLetters==
nullptr)
1266 return spellFxAniLetters->get_string(uint16_t(it.
spellId()));
1269bool GameScript::aiOutput(
Npc &npc, std::string_view outputname,
bool overlay) {
1279bool GameScript::aiOutputSvm(
Npc &npc, std::string_view outputname,
bool overlay) {
1286 if(!outputname.empty())
1287 return aiOutput(npc,outputname,overlay);
1308 return svm->find(
id,voice);
1312 auto blk = dialogs.block_by_name(
id);
1315 auto msg = blk->get_message();
1322 static std::string tmp;
1325 uint32_t& time = msgTimings[tmp];
1331 if(s.timeLength()>0) {
1332 time = uint32_t(s.timeLength());
1335 time = uint32_t(
float(txt.length())*viewTimePerChar);
1336 time = std::min(time, 16000u);
1342 auto id = vm.find_symbol_by_name(
"player_plunder_is_empty");
1349 vm.call_function<
void>(id);
1353 auto fn = vm.find_symbol_by_name(func);
1357 ScopeVar self(*vm.global_self(),hnpc);
1359 vm.call_function<
void>(fn);
1362 Log::i(
"unable to use interactive [",func,
"]");
1367 auto selfG = std::min<size_t>(gilCount-1,p0.
guild());
1368 auto npcG = std::min<size_t>(gilCount-1,p1.
guild());
1369 auto ret = gilAttitudes[selfG*gilCount+npcG];
1387 const int AIV_PARTYMEMBER = (owner.
version().game==2) ? 15 : 36;
1398 if(searchScheme(sc,
"MOB_SIT"))
1400 if(searchScheme(sc,
"MOB_LIE"))
1402 if(searchScheme(sc,
"MOB_CLIMB"))
1404 if(searchScheme(sc,
"MOB_NOTINTERRUPTABLE"))
1410 onWldInstanceRemoved(&itm.
handle());
1413void GameScript::onWldInstanceRemoved(
const zenkit::DaedalusInstance* obj) {
1414 vm.find_symbol_by_instance(*obj)->set_instance(
nullptr);
1417void GameScript::makeCurrent(
Item* w) {
1420 auto* s = vm.find_symbol_by_index(uint32_t(w->
clsId()));
1425bool GameScript::searchScheme(std::string_view sc, std::string_view listName) {
1426 std::string_view list =
findSymbol(listName)->get_string();
1427 for(
size_t i=0; i<=list.size(); ++i) {
1428 if(i==list.size() || list[i]==
',') {
1429 if(sc==list.substr(0,i))
1433 list = list.substr(i+1);
1440zenkit::DaedalusVm GameScript::createVm(
Gothic& gothic) {
1443 auto exef = zenkit::DaedalusVmExecutionFlag::ALLOW_NULL_INSTANCE_ACCESS;
1445 exef |= zenkit::DaedalusVmExecutionFlag::IGNORE_CONST_SPECIFIER;
1447 return zenkit::DaedalusVm(std::move(script), exef);
1451 return vm.find_symbol_by_name(name)!=
nullptr;
1464 return uint32_t(randGen())%max;
1467Npc* GameScript::findNpc(zenkit::DaedalusSymbol* s) {
1468 if(s->is_instance_of<zenkit::INpc>()) {
1469 auto cNpc =
reinterpret_cast<zenkit::INpc*
>(s->get_instance().get());
1470 return findNpc(cNpc);
1475Npc* GameScript::findNpc(zenkit::INpc *handle) {
1478 assert(handle->user_ptr);
1479 return reinterpret_cast<Npc*
>(handle->user_ptr);
1482Npc* GameScript::findNpc(
const std::shared_ptr<zenkit::INpc>& handle) {
1485 assert(handle->user_ptr);
1486 return reinterpret_cast<Npc*
>(handle->user_ptr);
1489Npc* GameScript::findNpcById(
const std::shared_ptr<zenkit::DaedalusInstance>& handle) {
1492 if(
auto npc =
dynamic_cast<const zenkit::INpc*
>(handle.get())) {
1493 assert(npc->user_ptr);
1494 return reinterpret_cast<Npc*
>(npc->user_ptr);
1496 return findNpcById(handle->symbol_index());
1499Item *GameScript::findItem(zenkit::IItem* handle) {
1502 auto& itData = *handle;
1503 assert(itData.user_ptr);
1504 return reinterpret_cast<Item*
>(itData.user_ptr);
1507Item *GameScript::findItemById(
size_t id) {
1508 auto* handle = vm.find_symbol_by_index(uint32_t(
id));
1509 if(handle==
nullptr||!handle->is_instance_of<zenkit::IItem>())
1511 auto hitm =
reinterpret_cast<zenkit::IItem*
>(handle->get_instance().get());
1512 return findItem(hitm);
1515Item* GameScript::findItemById(
const std::shared_ptr<zenkit::DaedalusInstance>& handle) {
1518 if(
auto itm =
dynamic_cast<const zenkit::IItem*
>(handle.get())) {
1519 assert(itm->user_ptr);
1520 return reinterpret_cast<Item*
>(itm->user_ptr);
1522 return findItemById(handle->symbol_index());
1525Npc* GameScript::findNpcById(
size_t id) {
1526 auto* handle = vm.find_symbol_by_index(uint32_t(
id));
1527 if(handle==
nullptr || !handle->is_instance_of<zenkit::INpc>())
1530 auto hnpc =
reinterpret_cast<zenkit::INpc*
>(handle->get_instance().get());
1533 handle->set_instance(obj ? obj->handlePtr() : nullptr);
1534 hnpc =
reinterpret_cast<zenkit::INpc*
>(handle->get_instance().get());
1536 return findNpc(hnpc);
1539zenkit::IInfo* GameScript::findInfo(
size_t id) {
1540 auto* sym = vm.find_symbol_by_index(uint32_t(
id));
1541 if(sym==
nullptr||!sym->is_instance_of<zenkit::IInfo>())
1543 auto* h = sym->get_instance().get();
1545 Log::e(
"invalid c_info object: \"",sym->name(),
"\"");
1546 return reinterpret_cast<zenkit::IInfo*
>(h);
1554 auto sym = vm.find_symbol_by_name(name);
1555 if(sym ==
nullptr) {
1556 Tempest::Log::e(
"Cannot set NPC instance ", name,
": Symbol not found.");
1563 storeItem(holder.
getItem(itemId));
1567 return aiDefaultPipe.get();
1577 auto id = vm.find_symbol_by_name(
"PLAYER_PERC_ASSESSMAGIC");
1582 return ScriptFn(uint32_t(id->get_int()));
1587 auto id = vm.find_symbol_by_name(
"NPC_DAM_DIVE_TIME");
1590 return id->get_int();
1594 return damCriticalMultiplier;
1598 return ItKE_lockpick!=
nullptr ? ItKE_lockpick->index() : 0;
1603 return dma->menuMain();
1607bool GameScript::game_initgerman() {
1611bool GameScript::game_initenglish() {
1615void GameScript::wld_settime(
int hour,
int minute) {
1619int GameScript::wld_getday() {
1620 return int(owner.
time().
day());
1623void GameScript::wld_playeffect(std::string_view visual, std::shared_ptr<zenkit::DaedalusInstance> sourceId, std::shared_ptr<zenkit::DaedalusInstance> targetId,
1624 int effectLevel,
int damage,
int damageType,
int isProjectile) {
1628 if(isProjectile!=0 || damageType!=0 || damage!=0 || effectLevel!=0) {
1630 Log::i(
"effect not implemented [",visual.data(),
"]");
1635 Log::i(
"invalid effect [",visual.data(),
"]");
1639 auto dstNpc = findNpcById(targetId);
1640 auto srcNpc = findNpcById(sourceId);
1642 auto dstItm = findItemById(targetId);
1643 auto srcItm = findItemById(sourceId);
1645 if(srcNpc!=
nullptr && dstNpc!=
nullptr) {
1646 srcNpc->startEffect(*dstNpc,*vfx);
1648 if(srcItm!=
nullptr && dstItm!=
nullptr){
1655void GameScript::wld_stopeffect(std::string_view visual) {
1658 Log::i(
"invalid effect [",visual.data(),
"]");
1661 if(
auto w = owner.
world())
1662 w->stopEffect(*vfx);
1665int GameScript::wld_getplayerportalguild() {
1667 if(
auto p =
world().player())
1672int GameScript::wld_getformerplayerportalguild() {
1674 if(
auto p =
world().player())
1679void GameScript::wld_setguildattitude(
int gil1,
int att,
int gil2) {
1680 if(gil1<0 || gil2<0 || gil1>=
int(gilCount) || gil2>=
int(gilCount))
1682 gilAttitudes[size_t(gil1)*gilCount+size_t(gil2)] = att;
1685int GameScript::wld_getguildattitude(
int gil1,
int gil2) {
1686 if(gil1<0 || gil2<0 || gil1>=
int(gilCount) || gil2>=
int(gilCount))
1688 return gilAttitudes[size_t(gil1)*gilCount+size_t(gil2)];
1691void GameScript::wld_exchangeguildattitudes(std::string_view name) {
1692 auto guilds = vm.find_symbol_by_name(name);
1695 for(
size_t i=0;i<gilTblSize;++i) {
1696 for(
size_t r=0;r<gilTblSize;++r)
1697 gilAttitudes[i*gilCount+r] = guilds->get_int(uint16_t(i * gilTblSize + r));
1701bool GameScript::wld_istime(
int hour0,
int min0,
int hour1,
int min1) {
1702 gtime begin{hour0,min0}, end{hour1,min1};
1706 if(begin<=end && begin<=now && now<end)
1708 else if(end<begin && (now<end || begin<=now))
1714bool GameScript::wld_isfpavailable(std::shared_ptr<zenkit::INpc> self, std::string_view name) {
1723bool GameScript::wld_isnextfpavailable(std::shared_ptr<zenkit::INpc> self, std::string_view name) {
1728 return fp !=
nullptr;
1731bool GameScript::wld_ismobavailable(std::shared_ptr<zenkit::INpc> self, std::string_view name) {
1732 auto npc = findNpc(self);
1738 return wp !=
nullptr;
1741void GameScript::wld_setmobroutine(
int h,
int m, std::string_view name,
int st) {
1745int GameScript::wld_getmobstate(std::shared_ptr<zenkit::INpc> npcRef, std::string_view scheme) {
1746 auto npc = findNpc(npcRef);
1757 return std::max(0,mob->stateId());
1760void GameScript::wld_assignroomtoguild(std::string_view name,
int g) {
1764bool GameScript::wld_detectnpc(std::shared_ptr<zenkit::INpc> npcRef,
int inst,
int state,
int guild) {
1765 auto npc = findNpc(npcRef);
1771 float dist=std::numeric_limits<float>::max();
1774 if((inst ==-1 || int32_t(n.instanceSymbol())==inst) &&
1775 (state==-1 || n.isInState(uint32_t(state))) &&
1776 (guild==-1 || int32_t(n.guild())==guild) &&
1777 (&n!=npc) && !n.isDead()) {
1778 float d = n.qDistTo(*npc);
1786 vm.global_other()->set_instance(ret->
handlePtr());
1787 return ret !=
nullptr;
1790bool GameScript::wld_detectnpcex(std::shared_ptr<zenkit::INpc> npcRef,
int inst,
int state,
int guild,
int player) {
1791 auto npc = findNpc(npcRef);
1796 float dist=std::numeric_limits<float>::max();
1799 if((inst ==-1 || int32_t(n.instanceSymbol())==inst) &&
1800 (state==-1 || n.isInState(uint32_t(state))) &&
1801 (guild==-1 || int32_t(n.guild())==guild) &&
1802 (&n!=npc) && !n.isDead() &&
1803 (player!=0 || !n.isPlayer())) {
1804 float d = n.qDistTo(*npc);
1812 vm.global_other()->set_instance(ret->
handlePtr());
1813 return ret !=
nullptr;
1816bool GameScript::wld_detectitem(std::shared_ptr<zenkit::INpc> npcRef,
int flags) {
1817 auto npc = findNpc(npcRef);
1823 float dist=std::numeric_limits<float>::max();
1825 if((it.handle().main_flag&flags)==0)
1827 float d = (npc->position()-it.position()).quadLength();
1835 vm.global_item()->set_instance(ret->
handlePtr());
1836 return ret !=
nullptr;
1839void GameScript::wld_spawnnpcrange(std::shared_ptr<zenkit::INpc> npcRef,
int clsId,
int count,
float lifeTime) {
1840 auto at = findNpc(npcRef);
1841 if(at==
nullptr || clsId<=0)
1845 for(int32_t i=0;i<count;++i) {
1846 auto* npc =
world().
addNpc(
size_t(clsId),at->position());
1847 fixNpcPosition(*npc,at->rotation()-90 + 360.f*
float(i)/
float(count),100);
1851void GameScript::wld_sendtrigger(std::string_view triggerTarget) {
1852 if(triggerTarget.empty())
1859void GameScript::wld_senduntrigger(std::string_view triggerTarget) {
1860 if(triggerTarget.empty())
1867bool GameScript::wld_israining() {
1868 static bool first=
true;
1870 Log::e(
"not implemented call [wld_israining]");
1876void GameScript::mdl_setvisual(std::shared_ptr<zenkit::INpc> npcRef, std::string_view visual) {
1877 auto npc = findNpc(npcRef);
1883void GameScript::mdl_setvisualbody(std::shared_ptr<zenkit::INpc> npcRef, std::string_view body,
int bodyTexNr,
int bodyTexColor, std::string_view head,
int headTexNr,
int teethTexNr,
int armor) {
1884 auto npc = findNpc(npcRef);
1888 npc->
setVisualBody(headTexNr,teethTexNr,bodyTexNr,bodyTexColor,body,head);
1891 npc->
addItem(uint32_t(armor),1);
1896void GameScript::mdl_setmodelfatness(std::shared_ptr<zenkit::INpc> npcRef,
float fat) {
1897 auto npc = findNpc(npcRef);
1902void GameScript::mdl_applyoverlaymds(std::shared_ptr<zenkit::INpc> npcRef, std::string_view overlayname) {
1903 auto npc = findNpc(npcRef);
1910void GameScript::mdl_applyoverlaymdstimed(std::shared_ptr<zenkit::INpc> npcRef, std::string_view overlayname,
int ticks) {
1911 auto npc = findNpc(npcRef);
1912 if(npc!=
nullptr && ticks>0) {
1918void GameScript::mdl_removeoverlaymds(std::shared_ptr<zenkit::INpc> npcRef, std::string_view overlayname) {
1919 auto npc = findNpc(npcRef);
1926void GameScript::mdl_setmodelscale(std::shared_ptr<zenkit::INpc> npcRef,
float x,
float y,
float z) {
1927 auto npc = findNpc(npcRef);
1932void GameScript::mdl_startfaceani(std::shared_ptr<zenkit::INpc> npcRef, std::string_view ani,
float intensity,
float time) {
1934 findNpc(npcRef.get())->
startFaceAnim(ani,intensity,uint64_t(time*1000.f));
1937void GameScript::mdl_applyrandomani(std::shared_ptr<zenkit::INpc> npcRef, std::string_view s1, std::string_view s0) {
1942 static bool first=
true;
1944 Log::e(
"not implemented call [mdl_applyrandomani]");
1949void GameScript::mdl_applyrandomanifreq(std::shared_ptr<zenkit::INpc> npcRef, std::string_view s1,
float f0) {
1954 static bool first=
true;
1956 Log::e(
"not implemented call [mdl_applyrandomanifreq]");
1961void GameScript::mdl_applyrandomfaceani(std::shared_ptr<zenkit::INpc> npcRef, std::string_view name,
float timeMin,
float timeMinVar,
float timeMax,
float timeMaxVar,
float probMin) {
1970 static bool first=
true;
1972 Log::e(
"not implemented call [mdl_applyrandomfaceani]");
1977void GameScript::wld_insertnpc(
int npcInstance, std::string_view spawnpoint) {
1981 auto npc =
world().
addNpc(
size_t(npcInstance),spawnpoint);
1986void GameScript::wld_removenpc(
int npcInstance) {
1987 if(
auto npc = findNpcById(
size_t(npcInstance)))
1991void GameScript::wld_insertitem(
int itemInstance, std::string_view spawnpoint) {
1992 if(spawnpoint.empty() || itemInstance<=0)
1998void GameScript::npc_settofightmode(std::shared_ptr<zenkit::INpc> npcRef,
int weaponSymbol) {
1999 if(npcRef!=
nullptr && weaponSymbol>=0)
2003void GameScript::npc_settofistmode(std::shared_ptr<zenkit::INpc> npcRef) {
2004 auto npc = findNpc(npcRef);
2009bool GameScript::npc_isinstate(std::shared_ptr<zenkit::INpc> npcRef,
int stateFn) {
2010 auto npc = findNpc(npcRef);
2012 return npc->
isInState(uint32_t(stateFn));
2016bool GameScript::npc_isinroutine(std::shared_ptr<zenkit::INpc> npcRef,
int stateFn) {
2017 auto npc = findNpc(npcRef);
2023bool GameScript::npc_wasinstate(std::shared_ptr<zenkit::INpc> npcRef,
int stateFn) {
2024 auto npc = findNpc(npcRef);
2030int GameScript::npc_getdisttowp(std::shared_ptr<zenkit::INpc> npcRef, std::string_view wpname) {
2031 auto npc = findNpc(npcRef);
2035 if(npc!=
nullptr && wp!=
nullptr){
2036 float ret = std::sqrt(npc->
qDistTo(wp));
2037 if(ret<
float(std::numeric_limits<int32_t>::max()))
2038 return int32_t(ret);
else
2039 return std::numeric_limits<int32_t>::max();
2041 return std::numeric_limits<int32_t>::max();
2045void GameScript::npc_exchangeroutine(std::shared_ptr<zenkit::INpc> npcRef, std::string_view rname) {
2046 auto npc = findNpc(npcRef);
2051 auto* sym = vm.find_symbol_by_name(name);
2052 size_t d = sym !=
nullptr ? sym->index() : 0;
2058bool GameScript::npc_isdead(std::shared_ptr<zenkit::INpc> npcRef) {
2059 auto npc = findNpc(npcRef);
2060 return npc==
nullptr ||
isDead(*npc);
2063bool GameScript::npc_knowsinfo(std::shared_ptr<zenkit::INpc> npcRef,
int infoinstance) {
2064 auto npc = findNpc(npcRef);
2068 zenkit::INpc& vnpc = npc->
handle();
2069 return doesNpcKnowInfo(vnpc, uint32_t(infoinstance));
2072void GameScript::npc_settalentskill(std::shared_ptr<zenkit::INpc> npcRef,
int t,
int lvl) {
2073 auto npc = findNpc(npcRef);
2078int GameScript::npc_gettalentskill(std::shared_ptr<zenkit::INpc> npcRef,
int skillId) {
2079 auto npc = findNpc(npcRef);
2083void GameScript::npc_settalentvalue(std::shared_ptr<zenkit::INpc> npcRef,
int t,
int lvl) {
2084 auto npc = findNpc(npcRef);
2089int GameScript::npc_gettalentvalue(std::shared_ptr<zenkit::INpc> npcRef,
int skillId) {
2090 auto npc = findNpc(npcRef);
2094void GameScript::npc_setrefusetalk(std::shared_ptr<zenkit::INpc> npcRef,
int timeSec) {
2095 auto npc = findNpc(npcRef);
2100bool GameScript::npc_refusetalk(std::shared_ptr<zenkit::INpc> npcRef) {
2101 auto npc = findNpc(npcRef);
2105int GameScript::npc_hasitems(std::shared_ptr<zenkit::INpc> npcRef,
int itemId) {
2106 auto npc = findNpc(npcRef);
2107 return npc!=
nullptr ? int(npc->
itemCount(uint32_t(itemId))) : 0;
2110bool GameScript::npc_hasspell(std::shared_ptr<zenkit::INpc> npcRef,
int splId) {
2111 auto npc = findNpc(npcRef);
2112 return npc!=
nullptr && npc->
inventory().hasSpell(splId);
2115int GameScript::npc_getinvitem(std::shared_ptr<zenkit::INpc> npcRef,
int itemId) {
2116 auto npc = findNpc(npcRef);
2117 auto itm = npc==
nullptr ? nullptr : npc->
getItem(uint32_t(itemId));
2120 return int(itm->
handle().symbol_index());
2129int GameScript::npc_getinvitembyslot(std::shared_ptr<zenkit::INpc> npcRef,
int cat,
int slotnr) {
2130 auto npc = findNpc(npcRef);
2166 Log::e(
"Unknown item category ", cat);
2171 auto itm = npc==
nullptr ? nullptr : npc->
inventory().findByFlags(f, uint32_t(slotnr));
2175 return itm!=
nullptr ? int(itm->
count()) : 0;
2178int GameScript::npc_removeinvitem(std::shared_ptr<zenkit::INpc> npcRef,
int itemId) {
2179 auto npc = findNpc(npcRef);
2181 npc->
delItem(uint32_t(itemId),1);
2185int GameScript::npc_removeinvitems(std::shared_ptr<zenkit::INpc> npcRef,
int itemId,
int amount) {
2186 auto npc = findNpc(npcRef);
2188 if(npc!=
nullptr && amount>0)
2189 npc->
delItem(uint32_t(itemId),uint32_t(amount));
2194int GameScript::npc_getbodystate(std::shared_ptr<zenkit::INpc> npcRef) {
2195 auto npc = findNpc(npcRef);
2202std::shared_ptr<zenkit::INpc> GameScript::npc_getlookattarget(std::shared_ptr<zenkit::INpc> npcRef) {
2203 auto npc = findNpc(npcRef);
2207int GameScript::npc_getdisttonpc(std::shared_ptr<zenkit::INpc> aRef, std::shared_ptr<zenkit::INpc> bRef) {
2208 auto a = findNpc(aRef);
2209 auto b = findNpc(bRef);
2211 if(a==
nullptr || b==
nullptr)
2212 return std::numeric_limits<int32_t>::max();
2214 float ret = std::sqrt(a->qDistTo(*b));
2215 if(ret>
float(std::numeric_limits<int32_t>::max()))
2216 return std::numeric_limits<int32_t>::max();
2220bool GameScript::npc_hasequippedarmor(std::shared_ptr<zenkit::INpc> npcRef) {
2221 auto npc = findNpc(npcRef);
2225void GameScript::npc_setperctime(std::shared_ptr<zenkit::INpc> npcRef,
float sec) {
2226 auto npc = findNpc(npcRef);
2231void GameScript::npc_percenable(std::shared_ptr<zenkit::INpc> npcRef,
int pr,
int fn) {
2232 auto npc = findNpc(npcRef);
2237void GameScript::npc_percdisable(std::shared_ptr<zenkit::INpc> npcRef,
int pr) {
2238 auto npc = findNpc(npcRef);
2243std::string GameScript::npc_getnearestwp(std::shared_ptr<zenkit::INpc> npcRef) {
2244 auto npc = findNpc(npcRef);
2251std::string GameScript::npc_getnextwp(std::shared_ptr<zenkit::INpc> npcRef) {
2252 auto npc = findNpc(npcRef);
2259void GameScript::npc_clearaiqueue(std::shared_ptr<zenkit::INpc> npcRef) {
2260 auto npc = findNpc(npcRef);
2265bool GameScript::npc_isplayer(std::shared_ptr<zenkit::INpc> npcRef) {
2266 auto npc = findNpc(npcRef);
2270int GameScript::npc_getstatetime(std::shared_ptr<zenkit::INpc> npcRef) {
2271 auto npc = findNpc(npcRef);
2277void GameScript::npc_setstatetime(std::shared_ptr<zenkit::INpc> npcRef,
int val) {
2278 auto npc = findNpc(npcRef);
2283void GameScript::npc_changeattribute(std::shared_ptr<zenkit::INpc> npcRef,
int atr,
int val) {
2284 auto npc = findNpc(npcRef);
2285 if(npc!=
nullptr && atr>=0)
2289bool GameScript::npc_isonfp(std::shared_ptr<zenkit::INpc> npcRef, std::string_view val) {
2290 auto npc = findNpc(npcRef);
2297 return w->isFreePoint();
2300int GameScript::npc_getheighttonpc(std::shared_ptr<zenkit::INpc> aRef, std::shared_ptr<zenkit::INpc> bRef) {
2301 auto a = findNpc(aRef);
2302 auto b = findNpc(bRef);
2304 if(a!=
nullptr && b!=
nullptr)
2305 ret = std::abs(a->position().y - b->position().y);
2306 return int32_t(ret);
2309std::shared_ptr<zenkit::IItem> GameScript::npc_getequippedmeleeweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2310 auto npc = findNpc(npcRef);
2317std::shared_ptr<zenkit::IItem> GameScript::npc_getequippedrangedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2318 auto npc = findNpc(npcRef);
2325std::shared_ptr<zenkit::IItem> GameScript::npc_getequippedarmor(std::shared_ptr<zenkit::INpc> npcRef) {
2326 auto npc = findNpc(npcRef);
2333bool GameScript::npc_canseenpc(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> otherRef) {
2336 auto other = findNpc(otherRef);
2337 auto npc = findNpc(npcRef);
2339 if(npc!=
nullptr && other!=
nullptr){
2345bool GameScript::npc_canseenpcfreelos(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> otherRef) {
2346 auto npc = findNpc(npcRef);
2347 auto oth = findNpc(otherRef);
2349 if(npc!=
nullptr && oth!=
nullptr){
2355bool GameScript::npc_canseeitem(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::IItem> itemRef) {
2356 auto npc = findNpc(npcRef);
2357 auto itm = findItem(itemRef.get());
2359 if(npc!=
nullptr && itm!=
nullptr){
2365bool GameScript::npc_hasequippedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2366 auto npc = findNpc(npcRef);
2367 return (npc!=
nullptr &&
2372bool GameScript::npc_hasequippedmeleeweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2373 auto npc = findNpc(npcRef);
2377bool GameScript::npc_hasequippedrangedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2378 auto npc = findNpc(npcRef);
2382int GameScript::npc_getactivespell(std::shared_ptr<zenkit::INpc> npcRef) {
2383 auto npc = findNpc(npcRef);
2395bool GameScript::npc_getactivespellisscroll(std::shared_ptr<zenkit::INpc> npcRef) {
2396 auto npc = findNpc(npcRef);
2401 if(w==
nullptr || !w->
isSpell())
2407bool GameScript::npc_isinfightmode(std::shared_ptr<zenkit::INpc> npcRef,
int modeI) {
2408 auto npc = findNpc(npcRef);
2435void GameScript::npc_settarget(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> otherRef) {
2436 auto oth = findNpc(otherRef);
2437 auto npc = findNpc(npcRef);
2449bool GameScript::npc_gettarget(std::shared_ptr<zenkit::INpc> npcRef) {
2450 auto npc = findNpc(npcRef);
2451 auto s = vm.global_other();
2453 if(npc!=
nullptr && npc->
target()) {
2458 s->set_instance(
nullptr);
2462bool GameScript::npc_getnexttarget(std::shared_ptr<zenkit::INpc> npcRef) {
2463 auto npc = findNpc(npcRef);
2467 float dist = float(npc->
handle().senses_range);
2471 if(&oth!=npc && !oth.isDown() && oth.isEnemy(*npc) && npc->canSenseNpc(oth,true)!=SensesBit::SENSE_NONE){
2472 float qd = oth.qDistTo(*npc);
2484 auto s = vm.global_other();
2489 s->set_instance(
nullptr);
2494void GameScript::npc_sendpassiveperc(std::shared_ptr<zenkit::INpc> npcRef,
int id, std::shared_ptr<zenkit::INpc> victimRef, std::shared_ptr<zenkit::INpc> otherRef) {
2495 auto npc = findNpc(npcRef);
2496 auto other = findNpc(otherRef);
2497 auto victim = findNpc(victimRef);
2499 if(npc && other && victim)
2501 else if(npc && other)
2505void GameScript::npc_sendsingleperc(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> otherRef,
int id) {
2506 auto other = findNpc(otherRef);
2507 auto npc = findNpc(npcRef);
2510 other->perceptionProcess(*npc,
nullptr,0,
PercType(
id));
2513bool GameScript::npc_checkinfo(std::shared_ptr<zenkit::INpc> npcRef,
int imp) {
2514 auto n = findNpc(npcRef);
2515 auto hero = findNpc(vm.global_other());
2516 if(n==
nullptr || hero==
nullptr)
2519 auto& pl = hero->handle();
2521 for(
auto& info:dialogsInfo) {
2522 if(info->npc!=int32_t(npc.symbol_index()) || info->important!=imp)
2524 bool npcKnowsInfo = doesNpcKnowInfo(pl,info->symbol_index());
2525 if(npcKnowsInfo && !info->permanent)
2528 if(info->condition) {
2529 auto* conditionSymbol = vm.find_symbol_by_index(uint32_t(info->condition));
2530 if (conditionSymbol !=
nullptr)
2531 valid = vm.call_function<
int>(conditionSymbol)!=0;
2540int GameScript::npc_getportalguild(std::shared_ptr<zenkit::INpc> npcRef) {
2542 auto npc = findNpc(npcRef);
2548bool GameScript::npc_isinplayersroom(std::shared_ptr<zenkit::INpc> npcRef) {
2549 auto npc = findNpc(npcRef);
2552 if(npc!=
nullptr && pl!=
nullptr) {
2561std::shared_ptr<zenkit::IItem> GameScript::npc_getreadiedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2562 auto npc = findNpc(npcRef);
2576bool GameScript::npc_hasreadiedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2577 auto npc = findNpc(npcRef);
2585bool GameScript::npc_hasreadiedmeleeweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2586 auto npc = findNpc(npcRef);
2594bool GameScript::npc_hasreadiedrangedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2595 auto npc = findNpc(npcRef);
2602bool GameScript::npc_hasrangedweaponwithammo(std::shared_ptr<zenkit::INpc> npcRef) {
2603 auto npc = findNpc(npcRef);
2604 return npc!=
nullptr && npc->
inventory().hasRangedWeaponWithAmmo();
2607int GameScript::npc_isdrawingspell(std::shared_ptr<zenkit::INpc> npcRef) {
2608 auto npc = findNpc(npcRef);
2613 if(ret==
nullptr || !ret->isSpell())
2617 return int32_t(ret->clsId());
2620int GameScript::npc_isdrawingweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2621 auto npc = findNpc(npcRef);
2626 if(ret==
nullptr || !ret->isSpell())
2630 return int32_t(ret->clsId());
2633void GameScript::npc_perceiveall(std::shared_ptr<zenkit::INpc> npcRef) {
2637void GameScript::npc_stopani(std::shared_ptr<zenkit::INpc> npcRef, std::string_view name) {
2638 auto npc = findNpc(npcRef);
2643int GameScript::npc_settrueguild(std::shared_ptr<zenkit::INpc> npcRef,
int gil) {
2644 auto npc = findNpc(npcRef);
2650int GameScript::npc_gettrueguild(std::shared_ptr<zenkit::INpc> npcRef) {
2651 auto npc = findNpc(npcRef);
2657void GameScript::npc_clearinventory(std::shared_ptr<zenkit::INpc> npcRef) {
2658 auto npc = findNpc(npcRef);
2663int GameScript::npc_getattitude(std::shared_ptr<zenkit::INpc> aRef, std::shared_ptr<zenkit::INpc> bRef) {
2664 auto a = findNpc(aRef);
2665 auto b = findNpc(bRef);
2667 if(a!=
nullptr && b!=
nullptr){
2674int GameScript::npc_getpermattitude(std::shared_ptr<zenkit::INpc> aRef, std::shared_ptr<zenkit::INpc> bRef) {
2675 auto a = findNpc(aRef);
2676 auto b = findNpc(bRef);
2678 if(a!=
nullptr && b!=
nullptr){
2685void GameScript::npc_setattitude(std::shared_ptr<zenkit::INpc> npcRef,
int att) {
2686 auto npc = findNpc(npcRef);
2691void GameScript::npc_settempattitude(std::shared_ptr<zenkit::INpc> npcRef,
int att) {
2692 auto npc = findNpc(npcRef);
2697bool GameScript::npc_hasbodyflag(std::shared_ptr<zenkit::INpc> npcRef,
int bodyflag) {
2698 auto npc = findNpc(npcRef);
2704int GameScript::npc_getlasthitspellid(std::shared_ptr<zenkit::INpc> npcRef) {
2705 auto npc = findNpc(npcRef);
2712int GameScript::npc_getlasthitspellcat(std::shared_ptr<zenkit::INpc> npcRef) {
2713 auto npc = findNpc(npcRef);
2719 return spell.spell_type;
2722void GameScript::npc_playani(std::shared_ptr<zenkit::INpc> npcRef, std::string_view name) {
2723 auto npc = findNpc(npcRef);
2728bool GameScript::npc_isdetectedmobownedbynpc(std::shared_ptr<zenkit::INpc> usrRef, std::shared_ptr<zenkit::INpc> npcRef) {
2729 auto npc = findNpc(npcRef);
2730 auto usr = findNpc(usrRef);
2732 if(npc!=
nullptr && usr!=
nullptr && usr->interactive()!=
nullptr){
2734 auto ow = usr->interactive()->ownerName();
2735 return inst->name() == ow;
2740bool GameScript::npc_isdetectedmobownedbyguild(std::shared_ptr<zenkit::INpc> npcRef,
int guild) {
2741 static bool first=
true;
2743 Log::e(
"not implemented call [npc_isdetectedmobownedbyguild]");
2747 auto npc = findNpc(npcRef);
2759std::string GameScript::npc_getdetectedmob(std::shared_ptr<zenkit::INpc> npcRef) {
2760 auto usr = findNpc(npcRef);
2761 if(usr!=
nullptr && usr->detectedMob()!=
nullptr){
2762 auto i = usr->detectedMob();
2763 return std::string(i->schemeName());
2768bool GameScript::npc_ownedbynpc(std::shared_ptr<zenkit::IItem> itmRef, std::shared_ptr<zenkit::INpc> npcRef) {
2769 auto npc = findNpc(npcRef);
2770 auto itm = findItem(itmRef.get());
2771 if(itm==
nullptr || npc==
nullptr) {
2775 auto* sym = vm.find_symbol_by_index(uint32_t(itm->
handle().owner));
2776 return sym !=
nullptr && npc->
handlePtr()==sym->get_instance();
2779bool GameScript::npc_canseesource(std::shared_ptr<zenkit::INpc> npcRef) {
2780 auto self = findNpc(npcRef);
2783 return self->canSeeSource();
2787bool GameScript::npc_isincutscene(std::shared_ptr<zenkit::INpc> npcRef) {
2788 auto npc = findNpc(npcRef);
2799int GameScript::npc_getdisttoitem(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::IItem> itmRef) {
2800 auto itm = findItem(itmRef.get());
2801 auto npc = findNpc(npcRef);
2802 if(itm==
nullptr || npc==
nullptr) {
2803 return std::numeric_limits<int32_t>::max();
2806 return int32_t(dp.length());
2809int GameScript::npc_getheighttoitem(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::IItem> itmRef) {
2810 auto itm = findItem(itmRef.get());
2811 auto npc = findNpc(npcRef);
2812 if(itm==
nullptr || npc==
nullptr) {
2813 return std::numeric_limits<int32_t>::max();
2816 return std::abs(dp);
2819int GameScript::npc_getdisttoplayer(std::shared_ptr<zenkit::INpc> npcRef) {
2821 auto npc = findNpc(npcRef);
2822 if(pl==
nullptr || npc==
nullptr) {
2823 return std::numeric_limits<int32_t>::max();
2825 auto dp = pl->position()-npc->
position();
2826 auto l = dp.length();
2827 if(l>
float(std::numeric_limits<int32_t>::max())) {
2828 return std::numeric_limits<int32_t>::max();
2833int GameScript::npc_getactivespellcat(std::shared_ptr<zenkit::INpc> npcRef) {
2834 auto npc = findNpc(npcRef);
2844 return spell.spell_type;
2847int GameScript::npc_setactivespellinfo(std::shared_ptr<zenkit::INpc> npcRef,
int v) {
2848 auto npc = findNpc(npcRef);
2854int GameScript::npc_getactivespelllevel(std::shared_ptr<zenkit::INpc> npcRef) {
2856 auto npc = findNpc(npcRef);
2862void GameScript::ai_processinfos(std::shared_ptr<zenkit::INpc> npcRef) {
2863 auto npc = findNpc(npcRef);
2864 auto pl = owner.
player();
2865 if(pl!=
nullptr && npc!=
nullptr) {
2871void GameScript::ai_output(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> targetRef, std::string_view outputname) {
2872 auto target = findNpc(targetRef);
2873 auto self = findNpc(selfRef);
2875 if(target==
nullptr && owner.
version().game==1)
2876 target = findNpc(vm.global_other());
2878 if(self!=
nullptr && target!=
nullptr) {
2884void GameScript::ai_stopprocessinfos(std::shared_ptr<zenkit::INpc> selfRef) {
2885 auto self = findNpc(selfRef);
2892void GameScript::ai_standup(std::shared_ptr<zenkit::INpc> selfRef) {
2893 auto self = findNpc(selfRef);
2898void GameScript::ai_standupquick(std::shared_ptr<zenkit::INpc> selfRef) {
2899 auto self = findNpc(selfRef);
2904void GameScript::ai_continueroutine(std::shared_ptr<zenkit::INpc> selfRef) {
2905 auto self = findNpc(selfRef);
2910void GameScript::ai_stoplookat(std::shared_ptr<zenkit::INpc> selfRef) {
2911 auto self = findNpc(selfRef);
2916void GameScript::ai_lookat(std::shared_ptr<zenkit::INpc> selfRef, std::string_view waypoint) {
2917 auto self = findNpc(selfRef);
2923void GameScript::ai_lookatnpc(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef) {
2924 auto npc = findNpc(npcRef);
2925 auto self = findNpc(selfRef);
2930void GameScript::ai_removeweapon(std::shared_ptr<zenkit::INpc> npcRef) {
2931 auto npc = findNpc(npcRef);
2936void GameScript::ai_unreadyspell(std::shared_ptr<zenkit::INpc> npcRef) {
2937 auto npc = findNpc(npcRef);
2942void GameScript::ai_turnaway(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef) {
2943 auto npc = findNpc(npcRef);
2944 auto self = findNpc(selfRef);
2949void GameScript::ai_turntonpc(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef) {
2950 auto npc = findNpc(npcRef);
2951 auto self = findNpc(selfRef);
2956void GameScript::ai_whirlaround(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> npcRef) {
2957 auto npc = findNpc(npcRef);
2958 auto self = findNpc(selfRef);
2963void GameScript::ai_outputsvm(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> targetRef, std::string_view name) {
2964 auto target = findNpc(targetRef);
2965 auto self = findNpc(selfRef);
2967 if(target==
nullptr && owner.
version().game==1)
2968 target = findNpc(vm.global_other());
2970 if(self!=
nullptr && target!=
nullptr) {
2976void GameScript::ai_outputsvm_overlay(std::shared_ptr<zenkit::INpc> selfRef, std::shared_ptr<zenkit::INpc> targetRef, std::string_view name) {
2977 auto target = findNpc(targetRef);
2978 auto self = findNpc(selfRef);
2980 if(target==
nullptr && owner.
version().game==1)
2981 target = findNpc(vm.global_other());
2983 if(self!=
nullptr && target!=
nullptr) {
2989void GameScript::ai_startstate(std::shared_ptr<zenkit::INpc> selfRef,
int func,
int state, std::string_view wp) {
2990 auto self = findNpc(selfRef);
2991 if(self!=
nullptr && func>0) {
2992 Npc* oth = findNpc(vm.global_other());
2993 Npc* vic = findNpc(vm.global_victim());
2994 auto& st =
aiState(
size_t(func));
2999void GameScript::ai_playani(std::shared_ptr<zenkit::INpc> npcRef, std::string_view name) {
3000 auto npc = findNpc(npcRef);
3005void GameScript::ai_setwalkmode(std::shared_ptr<zenkit::INpc> npcRef,
int modeBits) {
3006 int32_t weaponBit = 0x80;
3007 auto npc = findNpc(npcRef);
3009 int32_t mode = modeBits & (~weaponBit);
3010 if(npc!=
nullptr && mode>=0 && mode<=3){
3015void GameScript::ai_wait(std::shared_ptr<zenkit::INpc> npcRef,
float ms) {
3016 auto npc = findNpc(npcRef);
3017 if(npc!=
nullptr && ms>0)
3021void GameScript::ai_waitms(std::shared_ptr<zenkit::INpc> npcRef,
int ms) {
3022 auto npc = findNpc(npcRef);
3023 if(npc!=
nullptr && ms>0)
3027void GameScript::ai_aligntowp(std::shared_ptr<zenkit::INpc> npcRef) {
3028 auto npc = findNpc(npcRef);
3033void GameScript::ai_gotowp(std::shared_ptr<zenkit::INpc> npcRef, std::string_view waypoint) {
3034 auto npc = findNpc(npcRef);
3050void GameScript::ai_gotofp(std::shared_ptr<zenkit::INpc> npcRef, std::string_view waypoint) {
3051 auto npc = findNpc(npcRef);
3060void GameScript::ai_playanibs(std::shared_ptr<zenkit::INpc> npcRef, std::string_view ani,
int bs) {
3061 auto npc = findNpc(npcRef);
3066void GameScript::ai_equiparmor(std::shared_ptr<zenkit::INpc> npcRef,
int id) {
3067 auto npc = findNpc(npcRef);
3072void GameScript::ai_equipbestarmor(std::shared_ptr<zenkit::INpc> npcRef) {
3073 auto npc = findNpc(npcRef);
3078int GameScript::ai_equipbestmeleeweapon(std::shared_ptr<zenkit::INpc> npcRef) {
3079 auto npc = findNpc(npcRef);
3085int GameScript::ai_equipbestrangedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
3086 auto npc = findNpc(npcRef);
3092bool GameScript::ai_usemob(std::shared_ptr<zenkit::INpc> npcRef, std::string_view tg,
int state) {
3093 auto npc = findNpc(npcRef);
3099void GameScript::ai_teleport(std::shared_ptr<zenkit::INpc> npcRef, std::string_view tg) {
3100 auto npc = findNpc(npcRef);
3102 if(npc!=
nullptr && pt!=
nullptr)
3106void GameScript::ai_stoppointat(std::shared_ptr<zenkit::INpc> npcRef) {
3107 auto npc = findNpc(npcRef);
3112void GameScript::ai_drawweapon(std::shared_ptr<zenkit::INpc> npcRef) {
3113 auto npc = findNpc(npcRef);
3118void GameScript::ai_readymeleeweapon(std::shared_ptr<zenkit::INpc> npcRef) {
3119 auto npc = findNpc(npcRef);
3124void GameScript::ai_readyrangedweapon(std::shared_ptr<zenkit::INpc> npcRef) {
3125 auto npc = findNpc(npcRef);
3130void GameScript::ai_readyspell(std::shared_ptr<zenkit::INpc> npcRef,
int spell,
int mana) {
3131 auto npc = findNpc(npcRef);
3132 if(npc!=
nullptr && mana>0)
3136void GameScript::ai_attack(std::shared_ptr<zenkit::INpc> npcRef) {
3137 auto npc = findNpc(npcRef);
3142void GameScript::ai_flee(std::shared_ptr<zenkit::INpc> npcRef) {
3143 auto npc = findNpc(npcRef);
3148void GameScript::ai_dodge(std::shared_ptr<zenkit::INpc> npcRef) {
3149 auto npc = findNpc(npcRef);
3154void GameScript::ai_unequipweapons(std::shared_ptr<zenkit::INpc> npcRef) {
3155 auto npc = findNpc(npcRef);
3160void GameScript::ai_unequiparmor(std::shared_ptr<zenkit::INpc> npcRef) {
3161 auto npc = findNpc(npcRef);
3166void GameScript::ai_gotonpc(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> toRef) {
3167 auto to = findNpc(toRef);
3168 auto npc = findNpc(npcRef);
3173void GameScript::ai_gotonextfp(std::shared_ptr<zenkit::INpc> npcRef, std::string_view to) {
3174 auto npc = findNpc(npcRef);
3179void GameScript::ai_aligntofp(std::shared_ptr<zenkit::INpc> npcRef) {
3180 auto npc = findNpc(npcRef);
3185void GameScript::ai_useitem(std::shared_ptr<zenkit::INpc> npcRef,
int item) {
3186 auto npc = findNpc(npcRef);
3191void GameScript::ai_useitemtostate(std::shared_ptr<zenkit::INpc> npcRef,
int item,
int state) {
3192 auto npc = findNpc(npcRef);
3197void GameScript::ai_setnpcstostate(std::shared_ptr<zenkit::INpc> npcRef,
int state,
int radius) {
3198 auto npc = findNpc(npcRef);
3203void GameScript::ai_finishingmove(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> othRef) {
3204 auto oth = findNpc(othRef);
3205 auto npc = findNpc(npcRef);
3206 if(npc!=
nullptr && oth!=
nullptr)
3210void GameScript::ai_takeitem(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::IItem> itmRef) {
3211 auto itm = findItem(itmRef.get());
3212 auto npc = findNpc(npcRef);
3213 if(npc!=
nullptr && itm!=
nullptr)
3217void GameScript::ai_gotoitem(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::IItem> itmRef) {
3218 auto itm = findItem(itmRef.get());
3219 auto npc = findNpc(npcRef);
3220 if(npc!=
nullptr && itm!=
nullptr)
3224void GameScript::ai_pointat(std::shared_ptr<zenkit::INpc> npcRef, std::string_view waypoint) {
3225 auto npc = findNpc(npcRef);
3227 if(npc!=
nullptr && to!=
nullptr)
3231void GameScript::ai_pointatnpc(std::shared_ptr<zenkit::INpc> npcRef, std::shared_ptr<zenkit::INpc> otherRef) {
3232 auto other = findNpc(otherRef);
3233 auto npc = findNpc(npcRef);
3234 if(npc!=
nullptr && other!=
nullptr)
3238int GameScript::ai_printscreen(std::string_view msg,
int posx,
int posy, std::string_view font,
int timesec) {
3239 auto npc = findNpc(vm.global_self());
3250int GameScript::mob_hasitems(std::string_view tag,
int item) {
3251 return int(
world().hasItems(tag,uint32_t(item)));
3254void GameScript::ta_min(std::shared_ptr<zenkit::INpc> npcRef,
int start_h,
int start_m,
int stop_h,
int stop_m,
int action, std::string_view waypoint) {
3255 auto npc = findNpc(npcRef);
3260void GameScript::log_createtopic(std::string_view topicName,
int section) {
3265void GameScript::log_settopicstatus(std::string_view topicName,
int status) {
3273void GameScript::log_addentry(std::string_view topicName, std::string_view entry) {
3277void GameScript::equipitem(std::shared_ptr<zenkit::INpc> npcRef,
int cls) {
3278 auto self = findNpc(npcRef);
3280 if(self->itemCount(uint32_t(cls))==0)
3281 self->addItem(uint32_t(cls),1);
3286void GameScript::createinvitem(std::shared_ptr<zenkit::INpc> npcRef,
int itemInstance) {
3287 auto self = findNpc(npcRef);
3289 Item* itm = self->addItem(uint32_t(itemInstance),1);
3294void GameScript::createinvitems(std::shared_ptr<zenkit::INpc> npcRef,
int itemInstance,
int amount) {
3295 auto self = findNpc(npcRef);
3296 if(self!=
nullptr && amount>0) {
3297 Item* itm = self->addItem(uint32_t(itemInstance),
size_t(amount));
3302void GameScript::perc_setrange(
int perc,
int dist) {
3305 perceptionRanges.
range[perc] = dist;
3308int GameScript::hlp_getinstanceid(std::shared_ptr<zenkit::DaedalusInstance>
instance) {
3313int GameScript::hlp_random(
int bound) {
3314 uint32_t mod = uint32_t(std::max(1,bound));
3315 return int32_t(randGen() % mod);
3318bool GameScript::hlp_isvalidnpc(std::shared_ptr<zenkit::INpc> npcRef) {
3319 auto self = findNpc(npcRef);
3320 return self !=
nullptr;
3323bool GameScript::hlp_isitem(std::shared_ptr<zenkit::IItem> itemRef,
int instanceSymbol) {
3324 auto item = findItem(itemRef.get());
3326 auto& v = item->handle();
3327 return int(v.symbol_index()) == instanceSymbol;
3333bool GameScript::hlp_isvaliditem(std::shared_ptr<zenkit::IItem> itemRef) {
3334 auto item = findItem(itemRef.get());
3335 return item!=
nullptr;
3338std::shared_ptr<zenkit::INpc> GameScript::hlp_getnpc(
int instanceSymbol) {
3339 auto npc = findNpcById(uint32_t(instanceSymbol));
3346void GameScript::info_addchoice(
int infoInstance, std::string_view text,
int func) {
3347 auto info = findInfo(uint32_t(infoInstance));
3350 zenkit::IInfoChoice choice {};
3352 choice.function = func;
3353 info->add_choice(choice);
3356void GameScript::info_clearchoices(
int infoInstance) {
3357 auto info = findInfo(uint32_t(infoInstance));
3360 info->choices.clear();
3363bool GameScript::infomanager_hasfinished() {
3367void GameScript::snd_play(std::string_view fileS) {
3371 std::string file {fileS};
3373 c = char(std::toupper(c));
3377void GameScript::snd_play3d(std::shared_ptr<zenkit::INpc> npcRef, std::string_view fileS) {
3381 std::string file {fileS};
3382 Npc* npc = findNpc(npcRef);
3386 c = char(std::toupper(c));
3391void GameScript::exitsession() {
3395void GameScript::sort(std::vector<GameScript::DlgChoice> &dlg) {
3397 return std::tie(l.sort,l.scriptFn)<std::tie(r.sort,r.scriptFn);
3401void GameScript::setNpcInfoKnown(
const zenkit::INpc& npc,
const zenkit::IInfo& info) {
3402 auto id = std::make_pair(vm.find_symbol_by_instance(npc)->index(),vm.find_symbol_by_instance(info)->index());
3403 dlgKnownInfos.insert(
id);
3406bool GameScript::doesNpcKnowInfo(
const zenkit::INpc& npc,
size_t infoInstance)
const {
3407 auto id = std::make_pair(vm.find_symbol_by_instance(npc)->index(),infoInstance);
3408 return dlgKnownInfos.find(
id)!=dlgKnownInfos.end();
static AiAction aiPlayAnimBs(std::string_view ani, BodyState bs)
static AiAction aiTakeItem(Item &item)
static AiAction aiReadyRangedWeapon()
static AiAction aiEquipBestRangedWeapon()
static AiAction aiAlignToWp()
static AiAction aiUseMob(std::string_view name, int st)
static AiAction aiUseItemToState(int32_t id, int32_t state)
static AiAction aiGotoItem(Item &item)
static AiAction aiRemoveWeapon()
static AiAction aiDrawWeapon()
static AiAction aiStopLookAt()
static AiAction aiLookAtNpc(Npc *other)
static AiAction aiPointAtNpc(Npc &other)
static AiAction aiAttack()
static AiAction aiWhirlToNpc(Npc *other)
static AiAction aiTurnAway(Npc *other)
static AiAction aiPointAt(const WayPoint &to)
static AiAction aiStartState(ScriptFn stateFn, int behavior, Npc *other, Npc *victim, std::string_view wp)
static AiAction aiTurnToNpc(Npc *other)
static AiAction aiUnEquipArmor()
static AiAction aiReadyMeleeWeapon()
static AiAction aiPrintScreen(int time, std::string_view font, int x, int y, std::string_view msg)
static AiAction aiOutputSvmOverlay(Npc &to, std::string_view text, int order)
static AiAction aiReadySpell(int32_t spell, int32_t mana)
static AiAction aiDodge()
static AiAction aiSetNpcsToState(ScriptFn func, int32_t radius)
static AiAction aiUseItem(int32_t id)
static AiAction aiUnEquipWeapons()
static AiAction aiLookAt(const WayPoint *to)
static AiAction aiEquipBestArmor()
static AiAction aiStandup()
static AiAction aiProcessInfo(Npc &other)
static AiAction aiTeleport(const WayPoint &to)
static AiAction aiOutputSvm(Npc &to, std::string_view text, int order)
static AiAction aiSetWalkMode(WalkBit w)
static AiAction aiContinueRoutine()
static AiAction aiGoToNpc(Npc *other)
static AiAction aiGoToPoint(const WayPoint &to)
static AiAction aiAlignToFp()
static AiAction aiWait(uint64_t dt)
static AiAction aiEquipArmor(int32_t id)
static AiAction aiFinishingMove(Npc &other)
static AiAction aiGoToNextFp(std::string_view fp)
static AiAction aiStopProcessInfo(int order)
static AiAction aiEquipBestMeleeWeapon()
static AiAction aiStopPointAt()
static AiAction aiPlayAnim(std::string_view ani)
static AiAction aiStandupQuick()
static AiAction aiOutput(Npc &to, std::string_view text, int order)
std::u16string cutscenePath() const
static const CommandLine & inst()
static bool isRequired(zenkit::DaedalusScript &vm)
void printMobMissingKeyOrLockpick(Npc &npc)
void invokeRefreshAtInsert(Npc &npc)
size_t findSymbolIndex(std::string_view s)
Attitude guildAttitude(const Npc &p0, const Npc &p1) const
void printCannotCastError(Npc &npc, int32_t plM, int32_t itM)
uint32_t lockPickId() const
int invokeMana(Npc &npc, Npc *target, int mana)
bool hasSymbolName(std::string_view fn)
bool isTalk(const Npc &pl)
size_t symbolsCount() const
void printCannotUseError(Npc &npc, int32_t atr, int32_t nValue)
std::string_view spellCastAnim(Npc &npc, Item &fn)
std::string_view menuMain() const
uint32_t messageTime(std::string_view id) const
void playerHotLameHeal(Npc &pl)
int playerHotKeyScreenMap(Npc &pl)
void loadPerc(Serialize &fin)
void loadQuests(Serialize &fin)
int invokeCond(Npc &npc, std::string_view func)
void exec(const DlgChoice &dlg, Npc &player, Npc &npc)
bool isFriendlyFire(const Npc &src, const Npc &dst) const
std::string_view messageByName(std::string_view id) const
void printMobAnotherIsUsing(Npc &npc)
const AiState & aiState(ScriptFn id)
void initializeInstanceItem(const std::shared_ptr< zenkit::IItem > &item, size_t instance)
void fixNpcPosition(Npc &npc, float angle0, float distBias)
void useInteractive(const std::shared_ptr< zenkit::INpc > &hnpc, std::string_view func)
void loadVar(Serialize &fin)
void onWldItemRemoved(const Item &itm)
void invokeState(const std::shared_ptr< zenkit::INpc > &hnpc, const std::shared_ptr< zenkit::INpc > &hother, const char *name)
void removeItem(Item &it)
void printMobMissingItem(Npc &npc)
auto questLog() const -> const QuestLog &
zenkit::DaedalusSymbol * findSymbol(std::string_view s)
const zenkit::ISpell & spellDesc(int32_t splId)
std::string_view messageFromSvm(std::string_view id, int voice) const
AiOuputPipe * openAiOuput()
uint64_t tickCount() const
void printMobMissingKey(Npc &npc)
int playerHotKeyScreenMap_G1(Npc &pl)
AiOuputPipe * openDlgOuput(Npc &player, Npc &npc)
void printMobTooFar(Npc &npc)
GameScript(GameSession &owner)
bool isUnconscious(const Npc &pl)
void setInstanceItem(Npc &holder, size_t itemId)
void saveQuests(Serialize &fout)
int32_t criticalDamageMultiplyer() const
auto updateDialog(const GameScript::DlgChoice &dlg, Npc &player, Npc &npc) -> std::vector< GameScript::DlgChoice >
ScriptFn playerPercAssessMagic()
void invokeSpell(Npc &npc, Npc *target, Item &fn)
void playerHotLamePotion(Npc &pl)
uint32_t rand(uint32_t max)
Attitude personAttitude(const Npc &p0, const Npc &p1) const
int invokeManaRelease(Npc &npc, Npc *target, int mana)
void printCannotBuyError(Npc &npc)
auto dialogChoices(std::shared_ptr< zenkit::INpc > self, std::shared_ptr< zenkit::INpc > npc, const std::vector< uint32_t > &except, bool includeImp) -> std::vector< DlgChoice >
const VisualFx * spellVfx(int32_t splId)
bool isAttack(const Npc &pl) const
const World & world() const
auto canNpcCollideWithSpell(Npc &npc, Npc *shooter, int32_t spellId) -> CollideMask
void initializeInstanceNpc(const std::shared_ptr< zenkit::INpc > &npc, size_t instance)
void savePerc(Serialize &fout)
void printMobMissingLockpick(Npc &npc)
void invokeItem(Npc *npc, ScriptFn fn)
bool isDead(const Npc &pl)
void invokePickLock(Npc &npc, int bSuccess, int bBrokenOpen)
void saveVar(Serialize &fout)
void setInstanceNPC(std::string_view name, Npc &npc)
void eventPlayAni(Npc &npc, std::string_view ani)
BodyState schemeToBodystate(std::string_view sc)
uint64_t tickCount() const
bool isNpcInDialog(const Npc &npc) const
auto version() const -> const VersionInfo &
AiOuputPipe * openDlgOuput(Npc &player, Npc &npc)
const World * world() const
Tempest::Signal< void()> onSettingsChanged
Tempest::Signal< void(std::string_view, int, int, int, const GthFont &)> onPrintScreen
const World * world() const
zenkit::DaedalusScript loadScript(std::string_view datFile, const ScriptLang lang)
auto version() const -> const VersionInfo &
static int settingsGetI(std::string_view sec, std::string_view name)
std::string_view defaultGameDatFile() const
void setupVmCommonApi(zenkit::DaedalusVm &vm)
void emitGlobalSound(std::string_view sfx)
Tempest::Signal< void(std::string_view)> onPrint
void setupCommonScriptClasses(zenkit::DaedalusScript &sc)
auto loadVisualFx(std::string_view name) -> const VisualFx *
bool isSpellOrRune() const
const std::shared_ptr< zenkit::IItem > & handlePtr()
const zenkit::IItem & handle() const
Tempest::Vec3 position() const
static bool isClose(const Npc &npc, const Npc &p, float dist)
auto mapHeadBone() const -> Tempest::Vec3
void setToFightMode(const size_t item)
void setTalentSkill(Talent t, int32_t lvl)
float qDistTo(const Tempest::Vec3 pos) const
auto weaponState() const -> WeaponState
void stopAnim(std::string_view ani)
Attitude attitude() const
void addRoutine(gtime s, gtime e, uint32_t callback, std::string_view point)
const std::shared_ptr< zenkit::INpc > & handlePtr() const
auto currentWayPoint() const -> const WayPoint *
auto playAnimByName(std::string_view name, BodyState bs) -> const Animation::Sequence *
bool isInState(ScriptFn stateFn) const
bool canSeeNpc(const Npc &oth, bool freeLos) const
void setActiveSpellInfo(int32_t info)
Npc * lookAtTarget() const
bool wasInState(ScriptFn stateFn) const
void setVisualBody(int32_t headTexNr, int32_t teethTexNr, int32_t bodyVer, int32_t bodyColor, std::string_view body, std::string_view head)
void aiPush(AiQueue::AiAction &&a)
size_t itemCount(size_t id) const
void setRefuseTalk(uint64_t milis)
void setPerceptionDisable(PercType t)
int32_t talentSkill(Talent t) const
BodyState bodyState() const
bool setPosition(float x, float y, float z)
void setPerceptionEnable(PercType t, size_t fn)
int32_t talentValue(Talent t) const
int32_t activeSpellLevel() const
auto detectedMob() const -> Interactive *
void setVisual(std::string_view visual)
auto inventory() const -> const Inventory &
Item * currentMeleeWeapon()
void setTalentValue(Talent t, int32_t lvl)
void startFaceAnim(std::string_view anim, float intensity, uint64_t duration)
auto position() const -> Tempest::Vec3
void excRoutine(size_t callback)
void changeAttribute(Attribute a, int32_t val, bool allowUnconscious)
void useItem(size_t item)
void setStateTime(int64_t time)
uint32_t instanceSymbol() const
int32_t lastHitSpellId() const
void setAiOutputBarrier(uint64_t dt, bool overlay)
bool isRefuseTalk() const
void setAttitude(Attitude att)
void delItem(size_t id, uint32_t amount)
auto processPolicy() const -> NpcProcessPolicy
bool isTargetableBySpell(TargetType t) const
void setTempAttitude(Attitude att)
Item * currentRangedWeapon()
bool isInRoutine(ScriptFn stateFn) const
void setScale(float x, float y, float z)
void addOverlay(std::string_view sk, uint64_t time)
Item * addItem(size_t id, size_t amount)
uint64_t stateTime() const
Item * getItem(size_t id)
void setTrueGuild(int32_t g)
bool canSeeItem(const Item &it, bool freeLos) const
bool hasCollision() const
void delOverlay(std::string_view sk)
bool hasStateFlag(BodyState flg) const
void setPerceptionTime(uint64_t time)
auto portalName() -> std::string_view
int32_t trueGuild() const
void save(Serialize &fout)
void setStatus(std::string_view name, Status s)
void addEntry(std::string_view name, std::string_view entry)
void load(Serialize &fin)
Quest & add(std::string_view name, Section s)
static auto openReader(std::string_view name, std::unique_ptr< zenkit::Read > &read) -> std::unique_ptr< zenkit::ReadArchive >
static const Skeleton * loadSkeleton(std::string_view name)
static const GthFont & font(const float scale)
static bool hasFile(std::string_view fname)
static Tempest::Sound loadSoundBuffer(std::string_view name)
void write(const Arg &... a)
static const float talkRange
void sendPassivePerc(Npc &self, Npc &other, int32_t perc)
int32_t guildOfRoom(const Tempest::Vec3 &pos)
void addDlgSound(std::string_view s, const Tempest::Vec3 &pos, float range, uint64_t &timeLen)
void runEffect(Effect &&e)
void triggerEvent(const TriggerEvent &e)
const WayPoint * findNextWayPoint(const Npc &npc) const
DynamicWorld * physic() const
Interactive * availableMob(const Npc &pl, std::string_view name)
uint64_t tickCount() const
Npc * addNpc(std::string_view name, std::string_view at)
const WayPoint * findNextFreePoint(const Npc &pos, std::string_view name) const
const WayPoint * findPoint(std::string_view name, bool inexact=true) const
Item * itmById(uint32_t id)
uint32_t npcId(const Npc *ptr) const
Npc * findNpcByInstance(size_t instance, size_t n=0)
void removeItem(Item &it)
void detectItem(const Tempest::Vec3 &p, const float r, const std::function< void(Item &)> &f)
Npc * npcById(uint32_t id)
Item * addItem(size_t itemInstance, std::string_view at)
void detectNpc(const Tempest::Vec3 &p, const float r, const std::function< void(Npc &)> &f)
const WayPoint * findFreePoint(const Npc &pos, std::string_view name) const
void setMobRoutine(gtime time, std::string_view scheme, int32_t state)
const WayPoint * findWayPoint(std::string_view name) const
void setDayTime(int32_t h, int32_t min)
void assignRoomToGuild(std::string_view room, int32_t guildId)
static CommandLine * instance
@ BS_MOBINTERACT_INTERRUPT
bool exists(const std::u16string &path)
std::u16string caseInsensitiveSegment(std::u16string_view path, const char16_t *segment, Tempest::Dir::FileType type)
int32_t range[PERC_Count]
int at(PercType perc, int r) const
ScopeCtx(GameScript &script, NpcProcessPolicy pp)
ScopeVar(const ScopeVar &)=delete
ScopeVar(zenkit::DaedalusSymbol &sym, const std::shared_ptr< T > &h)
std::shared_ptr< zenkit::DaedalusInstance > prev
zenkit::DaedalusSymbol & sym