/* Set up the locals dictionary for executing dialog guards and actions. */ static PyObject* CreateDialogLocals(const DialogState* dialog, int pickedLine) { auto locals = PyDict_New(); auto pcObj = PyObjHndl_Create(dialog->pc); PyDict_SetItemString(locals, "pc", pcObj); Py_DECREF(pcObj); auto npcObj = PyObjHndl_Create(dialog->npc); PyDict_SetItemString(locals, "npc", npcObj); Py_DECREF(npcObj); auto lineObj = PyInt_FromLong(pickedLine); PyDict_SetItemString(locals, "picked_line", lineObj); Py_DECREF(lineObj); return locals; }
static int RunPythonObjScript(ObjScriptInvocation* invoc) { // This seems to be primarily used by the CounterArray pythonObjIntegration.SetCounterContext(invoc->attachee, invoc->script->scriptId, invoc->evt); pythonObjIntegration.SetInObjInvocation(true); PyObject* args; auto triggerer = PyObjHndl_Create(invoc->triggerer); // Expected arguments depend on the event type if (invoc->evt == ObjScriptEvent::SpellCast) { auto attachee = PyObjHndl_Create(invoc->attachee); auto spell = PySpell_Create(invoc->spellId); args = Py_BuildValue("OOO", attachee, triggerer, spell); Py_DECREF(spell); Py_DECREF(attachee); } else if (invoc->evt == ObjScriptEvent::Trap) { auto attachee = PyTrap_Create(invoc->attachee); args = Py_BuildValue("OO", attachee, triggerer); Py_DECREF(attachee); } else { if (invoc->evt == ObjScriptEvent::FirstHeartbeat){ int dumy = 1; } auto attachee = PyObjHndl_Create(invoc->attachee); args = Py_BuildValue("OO", attachee, triggerer); Py_DECREF(attachee); } auto result = pythonObjIntegration.RunScript(invoc->script->scriptId, (PythonIntegration::EventId) invoc->evt, args); Py_DECREF(args); auto newSid = pythonObjIntegration.GetNewSid(); if (newSid != -1 && newSid != invoc->script->scriptId) { invoc->script->scriptId = newSid; } pythonObjIntegration.SetInObjInvocation(false); return result; }
/* Calls into rumor_control.find_rumor. Quote from the python function: # this function returns the message line (0, 10, 20, etc) of a # rumor to be told to the PC in question, or -1 if no rumor is # available */ static int __cdecl RumorFind(objHndl pc, objHndl npc) { auto args = PyTuple_New(2); PyTuple_SET_ITEM(args, 0, PyObjHndl_Create(pc)); PyTuple_SET_ITEM(args, 1, PyObjHndl_Create(npc)); auto result = pythonObjIntegration.ExecuteScript("rumor_control", "find_rumor", args); auto rumorId = -1; if (PyInt_Check(result)) { rumorId = PyInt_AsLong(result); if (rumorId != -1) { rumorId /= 10; } } Py_DECREF(result); Py_DECREF(args); logger->debug("Rumor found: {}", rumorId); return rumorId; }
/* Calls pc_start.pc_start */ static void PcStart(objHndl pc) { inventory.Clear(pc, FALSE); // This checks that the PC has at least one level in any of the classes auto stat = d20ClassSys.classEnums[0]; auto classIndex = 0; while (classIndex <= NUM_CLASSES) { stat = d20ClassSys.classEnums[classIndex]; if (objects.StatLevelGet(pc, stat) > 0) break; classIndex++; if (classIndex >= NUM_CLASSES) return; } try { auto content(MesFile::ParseFile("rules\\start_equipment.mes")); auto key = classIndex; // Modify for "small" races auto race = critterSys.GetRace(pc); if (race == race_halfling || race == race_gnome) { key += 100; } auto it = content.find(key); if (it != content.end()) { auto protoIds = split(it->second, ' ', true); for (auto protoIdStr : protoIds) { auto protoId = stoi(protoIdStr); critterSys.GiveItem(pc, protoId); } } auto args = PyTuple_New(1); PyTuple_SET_ITEM(args, 0, PyObjHndl_Create(pc)); auto result = pythonObjIntegration.ExecuteScript("pc_start", "pc_start", args); Py_DECREF(result); Py_DECREF(args); } catch (TempleException& e) { logger->warn("Unable to load starting equipment: {}", e.what()); } inventory.WieldBestAll(pc, 0); }
void PythonObjIntegration::RunAnimFrameScript(const std::string &command) { logger->trace("Running Python command {}", command); auto locals = PyDict_New(); // Put the anim obj into the locals auto animObj = PyObjHndl_Create(mAnimatedObj); PyDict_SetItemString(locals, "anim_obj", animObj); Py_DECREF(animObj); auto result = PyRun_String(command.c_str(), Py_eval_input, MainModuleDict, locals); Py_DECREF(locals); if (!result) { PyErr_Print(); } else { Py_DECREF(result); } }
void PythonSpellIntegration::SpellTriggerProjectile(int spellId, SpellEvent evt, objHndl projectile, int targetIdx) { auto pySpell = PySpell_Create(spellId); auto projectileObj = PyObjHndl_Create(projectile); auto args = Py_BuildValue("(OOi)", pySpell, projectileObj, targetIdx); Py_DECREF(projectileObj); auto spellEnum = spellSys.GetSpellEnumFromSpellId(spellId); auto result = RunScript(spellEnum, (EventId)evt, args); Py_DECREF(args); // The meaning of the results is different from obj scripts if (result == -1 || result == 0) { PySpell_UpdatePacket(pySpell); SpellPacketBody spellPktBody; spellSys.GetSpellPacketBody(spellId, &spellPktBody); addresses.SpellProjectileSoundPlay(&spellPktBody, evt, projectile); } Py_DECREF(pySpell); }