예제 #1
0
/*
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;
}
예제 #2
0
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;
}
예제 #3
0
/*
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;
}
예제 #4
0
/*
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);
}
예제 #5
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);
}