Skip to content

Commit

Permalink
Arcane Archer - added support for Cone spells
Browse files Browse the repository at this point in the history
(Added flag PickOrigin to Cone targeting, expanded D20Action API to modify pickers)
  • Loading branch information
DMD authored and DMD committed Mar 11, 2017
1 parent 49dac8c commit 3a691bf
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 26 deletions.
7 changes: 5 additions & 2 deletions TemplePlus/action_sequence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,14 +424,17 @@ void ActionSequenceSystem::ActSeqGetPicker(){
auto curSeq = *actSeqSys.actSeqCur;
curSeq->spellPktBody.spellRange *= ((MetaMagicData)metaMagicData).metaMagicEnlargeSpellCount + 1;
SpellEntry spellEntry;
if (spellSys.spellRegistryCopy(spellEnum, &spellEntry))
{
if (spellSys.spellRegistryCopy(spellEnum, &spellEntry)){
spellEntry.radiusTarget *= ((MetaMagicData)metaMagicData).metaMagicWidenSpellCount + 1;
}
PickerArgs pickArgs;
spellSys.pickerArgsFromSpellEntry(&spellEntry, &pickArgs, curSeq->spellPktBody.caster, curSeq->spellPktBody.casterLevel);
pickArgs.spellEnum = spellEnum;
pickArgs.callback = [](const PickerResult & result, void* cbArgs) { actSeqSys.SpellPickerCallback(result, (SpellPacketBody*)cbArgs); };
// Modify the PickerArgs
if (d20Sys.globD20Action->d20ActType == D20A_PYTHON_ACTION)
pythonD20ActionIntegration.ModifyPicker(d20Sys.globD20Action->data1, &pickArgs);

*actSeqPickerActive = 1;
uiPicker.ShowPicker(pickArgs, &curSeq->spellPktBody);
*addresses.actSeqPickerAction = *d20Sys.globD20Action;
Expand Down
4 changes: 3 additions & 1 deletion TemplePlus/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ enum class UiPickerType : uint64_t {
Any30Feet = 0x800,
Primary30Feet = 0x1000,
EndEarlyMulti = 0x2000,
LocIsClear = 0x4000
LocIsClear = 0x4000,
PickOrigin = 0x8000 // New! denotes that the spell's point of origin can be freely chosen
};

struct ObjListResultItem {
Expand Down Expand Up @@ -304,6 +305,7 @@ struct ObjListResult
void PrependHandle(objHndl handle);
void IncreaseObjListCount();
int CountResults();
void ListRadius(LocAndOffsets origin, float rangeInches, float angleMin, float angleMax, int filter);

};

Expand Down
23 changes: 22 additions & 1 deletion TemplePlus/location.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ LocAndOffsets LocationSys::TrimToLength(LocAndOffsets srcLoc, LocAndOffsets tgtL
float LocationSys::AngleBetweenPoints(LocAndOffsets &fromPoint, LocAndOffsets &toPoint)
{
auto fromCoord = fromPoint.ToInches2D();
auto toCoord = fromPoint.ToInches2D();
auto toCoord = toPoint.ToInches2D();

// Create the vector from->to
auto dir = XMFLOAT2(
Expand All @@ -230,6 +230,27 @@ float LocationSys::AngleBetweenPoints(LocAndOffsets &fromPoint, LocAndOffsets &t
return angle + 2.3561945f; // + 135 degrees
}

XMFLOAT2 LocationSys::GetDirectionVector(LocAndOffsets & fromPoint, LocAndOffsets & toPoint)
{
auto fromCoord = fromPoint.ToInches2D();
auto toCoord = toPoint.ToInches2D();

// Create the vector from->to
auto dir = XMFLOAT2(
toCoord.x - fromCoord.x,
toCoord.y - fromCoord.y
);

auto normalizer = sqrt(dir.x * dir.x + dir.y * dir.y);
if (normalizer > 0){
dir.x = dir.x / normalizer;
dir.y = dir.y / normalizer;
}


return dir;
}

LocationSys::LocationSys()
{
rebase(getLocAndOff, 0x10040080);
Expand Down
2 changes: 2 additions & 0 deletions TemplePlus/location.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ struct LocationSys : temple::AddressTable
*/
float AngleBetweenPoints(LocAndOffsets &fromPoint, LocAndOffsets &toPoint);

XMFLOAT2 GetDirectionVector(LocAndOffsets &fromPoint, LocAndOffsets &toPoint); // returns a normalized vector in the direction from -> to

LocationSys();
};

Expand Down
6 changes: 5 additions & 1 deletion TemplePlus/objlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ static struct ObjListAddresses : temple::AddressTable {
void(__cdecl *ObjListTile)(locXY loc, int flags, ObjListResult &result);
void(__cdecl *ObjListRect)(TileRect &trect, ObjectListFilter olcCritters, ObjListResult& result);
void(__cdecl *ObjListVicinity)(locXY loc, int flags, ObjListResult &result);
void(__cdecl *ObjListRadius)(LocAndOffsets loc, float radius, float unk1, float unk2, int flags, ObjListResult &result);
void(__cdecl *ObjListRadius)(LocAndOffsets loc, float radius, float angleMin, float angleMax, int flags, ObjListResult &result);
void(__cdecl *ObjListFollowers)(objHndl critter, ObjListResult &result);
int(__cdecl *ObjListFree)(ObjListResult &result);
ObjListResultItem *(__cdecl*ObjlistPop)();
Expand Down Expand Up @@ -57,6 +57,10 @@ int ObjListResult::CountResults(){
return count;
}

void ObjListResult::ListRadius(LocAndOffsets origin, float rangeInches, float angleMin, float angleSize, int filter){
addresses.ObjListRadius(origin, rangeInches, angleMin, angleSize, filter, *this);
}

ObjList::ObjList() {
FreeResult();
}
Expand Down
42 changes: 42 additions & 0 deletions TemplePlus/python/python_integration_d20_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "d20.h"
#include "action_sequence.h"
#include "float_line.h"
#include "ui/ui_picker.h"

namespace py = pybind11;
using namespace pybind11;
Expand Down Expand Up @@ -54,6 +55,29 @@ PYBIND11_PLUGIN(tp_actions) {
})
;

py::class_<PickerArgs>(m, "PickerArgs")
.def_readwrite("spell_enum", &PickerArgs::spellEnum)
.def_readwrite("caster", &PickerArgs::caster)
.def_readwrite("mode_target", &PickerArgs::modeTarget)
.def("get_base_mode_target", &PickerArgs::GetBaseModeTarget)
.def("set_mode_target_flag", &PickerArgs::SetModeTargetFlag)
.def("is_mode_target_flag_set", &PickerArgs::IsModeTargetFlagSet)
;

py::enum_<UiPickerType>(m, "ModeTarget")
.value("Single", UiPickerType::Single)
.value("Cone", UiPickerType::Cone)
.value("Area", UiPickerType::Area)
.value("Personal", UiPickerType::Personal)
.value("Ray", UiPickerType::Ray)
.value("Wall", UiPickerType::Wall)
.value("EndEarlyMulti", UiPickerType::EndEarlyMulti)
.value("OnceMulti", UiPickerType::OnceMulti)
.value("Any30Feet", UiPickerType::Any30Feet)
.value("PickOrigin", UiPickerType::PickOrigin)
.export_values()
;

m.def("add_to_seq", [](D20Actn & d20a, ActnSeq & actSeq){
actSeq.d20ActArray[actSeq.d20ActArrayNum++] = d20a;
});
Expand Down Expand Up @@ -154,6 +178,23 @@ int PythonD20ActionIntegration::GetTargetingClassification(int actionEnum){
return GetInt(actionEnum, D20ActionSpecFunc::GetTargetingClassification);
}

void PythonD20ActionIntegration::ModifyPicker(int actionEnum, PickerArgs * pickArgs){
auto actionSpecEntry = mScripts.find(actionEnum);
if (actionSpecEntry == mScripts.end()) {
return;
}

py::object pbPicker = py::cast(pickArgs);

auto dispPyArgs = Py_BuildValue("(O)", pbPicker.ptr());

auto result = (ActionErrorCode)RunScriptDefault0(actionSpecEntry->second.id, (EventId)D20ActionSpecFunc::ModifyPicker, dispPyArgs);

Py_DECREF(dispPyArgs);

return;
}

ActionCostType PythonD20ActionIntegration::GetActionCostType(int actionEnum){
return (ActionCostType)GetInt(actionEnum, D20ActionSpecFunc::GetActionCostType);
}
Expand Down Expand Up @@ -218,6 +259,7 @@ static std::map<D20ActionSpecFunc, std::string> D20ActionSpecFunctions = {
{ D20ActionSpecFunc::GetTargetingClassification,"GetTargetingClassification" },
{ D20ActionSpecFunc::GetActionCostType,"GetActionCostType" },
{ D20ActionSpecFunc::AddToSequence,"AddToSequence" },
{ D20ActionSpecFunc::ModifyPicker,"ModifyPicker" },
{ D20ActionSpecFunc::ProjectileHit,"ProjectileHit" },


Expand Down
3 changes: 3 additions & 0 deletions TemplePlus/python/python_integration_d20_action.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ enum class D20ActionSpecFunc : int {
GetTargetingClassification,
GetActionCostType,
AddToSequence,
ModifyPicker,
ProjectileHit
};


struct D20Actn;
struct ActnSeq;
struct TurnBasedStatus;
struct PickerArgs;
enum ActionErrorCode : uint32_t;

class PythonD20ActionIntegration : public PythonIntegration {
Expand All @@ -29,6 +31,7 @@ class PythonD20ActionIntegration : public PythonIntegration {

int GetActionDefinitionFlags(int actionEnum);
int GetTargetingClassification(int actionEnum);
void ModifyPicker(int actionEnum, PickerArgs * pickArgs);
ActionCostType GetActionCostType(int actionEnum);


Expand Down
18 changes: 18 additions & 0 deletions TemplePlus/python/python_spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,24 @@ static PyObject* PySpellStore_IsAreaSpell(PyObject* obj, PyObject* args) {
}

return PyInt_FromLong(spEntry.IsBaseModeTarget(UiPickerType::Area));
}

static PyObject* PySpellStore_IsModeTarget(PyObject* obj, PyObject* args) {
auto self = (PySpellStore*)obj;
if (!self->spellData.spellEnum)
return PyInt_FromLong(0);

SpellEntry spEntry(self->spellData.spellEnum);
if (!spEntry.spellEnum) {
return PyInt_FromLong(0);
}

int modeTarget;
if (!PyArg_ParseTuple(args, "i:PySpellStore.is_mode_target", &modeTarget)) {
return PyInt_FromLong(0);
}

return PyInt_FromLong(spEntry.IsBaseModeTarget((UiPickerType)modeTarget));
}

static PyObject* PySpellStore_IsUsedUp(PyObject* obj, PyObject* args) {
Expand All @@ -1111,6 +1128,7 @@ static PyObject* PySpellStore_IsUsedUp(PyObject* obj, PyObject* args) {

static PyMethodDef PySpellStoreMethods[] = {
{"is_area_spell", PySpellStore_IsAreaSpell, METH_VARARGS, NULL },
{"is_mode_target", PySpellStore_IsModeTarget, METH_VARARGS, NULL },
{"is_naturally_cast", PySpellStore_IsNaturallyCast, METH_VARARGS, NULL },
{"is_used_up", PySpellStore_IsUsedUp, METH_VARARGS, NULL },
{ NULL, NULL, NULL, NULL }
Expand Down
Loading

0 comments on commit 3a691bf

Please sign in to comment.