From 956e5f9daead6d746b4a80f5428e8951bab9280f Mon Sep 17 00:00:00 2001 From: Nicholas Logan Date: Sun, 1 Aug 2021 14:16:32 -0400 Subject: [PATCH] DeleteShot functions now return number of shots deleted. Added DeleteShotInRegularPolygon. --- source/TouhouDanmakufu/Common/StgShot.cpp | 56 +++++++++++++++++- source/TouhouDanmakufu/Common/StgShot.hpp | 3 +- .../TouhouDanmakufu/Common/StgStageScript.cpp | 37 ++++++++++-- .../TouhouDanmakufu/Common/StgStageScript.hpp | 1 + .../DnhExecutor/th_dnh_poup.ico | Bin 0 -> 16958 bytes 5 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 source/TouhouDanmakufu/DnhExecutor/th_dnh_poup.ico diff --git a/source/TouhouDanmakufu/Common/StgShot.cpp b/source/TouhouDanmakufu/Common/StgShot.cpp index 97e38007..a12393ec 100644 --- a/source/TouhouDanmakufu/Common/StgShot.cpp +++ b/source/TouhouDanmakufu/Common/StgShot.cpp @@ -186,7 +186,7 @@ void StgShotManager::AddShot(ref_unsync_ptr obj) { listObj_.push_back(obj); } -void StgShotManager::DeleteInCircle(int typeDelete, int typeTo, int typeOwner, int cx, int cy, int* radius) { +size_t StgShotManager::DeleteInCircle(int typeDelete, int typeTo, int typeOwner, int cx, int cy, int* radius) { int r = radius ? *radius : 0; int rr = r * r; @@ -195,6 +195,8 @@ void StgShotManager::DeleteInCircle(int typeDelete, int typeTo, int typeOwner, i int rect_x2 = cx + r; int rect_y2 = cy + r; + size_t res = 0; + for (ref_unsync_ptr& obj : listObj_) { if (obj->IsDeleted()) continue; if ((typeOwner != StgShotObject::OWNER_NULL) && (obj->GetOwnerType() != typeOwner)) continue; @@ -215,8 +217,60 @@ void StgShotManager::DeleteInCircle(int typeDelete, int typeTo, int typeOwner, i obj->SetFadeDelete(); else if (typeTo == TO_TYPE_ITEM) obj->ConvertToItem(false); + ++res; + } + } + + return res; +} +size_t StgShotManager::DeleteInRegularPolygon(int typeDelete, int typeTo, int typeOwner, int cx, int cy, int* radius, int edges, double angle) { + int r = radius ? *radius : 0; + + int rect_x1 = cx - r; + int rect_y1 = cy - r; + int rect_x2 = cx + r; + int rect_y2 = cy + r; + + size_t res = 0; + + for (ref_unsync_ptr& obj : listObj_) { + if (obj->IsDeleted()) continue; + if ((typeOwner != StgShotObject::OWNER_NULL) && (obj->GetOwnerType() != typeOwner)) continue; + if (typeDelete == DEL_TYPE_SHOT && obj->IsSpellResist()) continue; + + int sx = obj->GetPositionX(); + int sy = obj->GetPositionY(); + + bool bInPolygon = radius == nullptr; + if (!bInPolygon && ((sx > rect_x1 && sy > rect_y1) && (sx < rect_x2 && sy < rect_y2))) { + float f = GM_PI / (float) edges; + float cf = cosf(f); + float dx = sx - cx; + float dy = sy - cy; + float dist = hypotf(dy, dx); + + bInPolygon = dist <= r; + if (bInPolygon) { + double r_apothem = r * cf; + bInPolygon = dist <= r_apothem; + if (!bInPolygon) { + double ang = fmod(Math::NormalizeAngleRad(atan2(dy, dx)) - Math::DegreeToRadian(angle), 2 * f); + bInPolygon = dist <= (r_apothem / cos(ang - f)); + } + } + } + if (bInPolygon) { + if (typeTo == TO_TYPE_IMMEDIATE) + obj->DeleteImmediate(); + else if (typeTo == TO_TYPE_FADE) + obj->SetFadeDelete(); + else if (typeTo == TO_TYPE_ITEM) + obj->ConvertToItem(false); + ++res; } } + + return res; } std::vector StgShotManager::GetShotIdInCircle(int typeOwner, int cx, int cy, int* radius) { diff --git a/source/TouhouDanmakufu/Common/StgShot.hpp b/source/TouhouDanmakufu/Common/StgShot.hpp index 790dcf9b..32e5ea44 100644 --- a/source/TouhouDanmakufu/Common/StgShot.hpp +++ b/source/TouhouDanmakufu/Common/StgShot.hpp @@ -72,7 +72,8 @@ class StgShotManager { void SetShotDeleteClip(const DxRect& clip) { rcDeleteClip_ = clip; } DxRect* GetShotDeleteClip() { return &rcDeleteClip_; } - void DeleteInCircle(int typeDelete, int typeTo, int typeOwner, int cx, int cy, int* radius); + size_t DeleteInCircle(int typeDelete, int typeTo, int typeOwner, int cx, int cy, int* radius); + size_t DeleteInRegularPolygon(int typeDelete, int typeTo, int typeOwner, int cx, int cy, int* radius, int edges, double angle); std::vector GetShotIdInCircle(int typeOwner, int cx, int cy, int* radius); size_t GetShotCount(int typeOwner); size_t GetShotCountAll() { return listObj_.size(); } diff --git a/source/TouhouDanmakufu/Common/StgStageScript.cpp b/source/TouhouDanmakufu/Common/StgStageScript.cpp index f66d28e2..ebc0dcea 100644 --- a/source/TouhouDanmakufu/Common/StgStageScript.cpp +++ b/source/TouhouDanmakufu/Common/StgStageScript.cpp @@ -317,6 +317,7 @@ static const std::vector stgStageFunction = { //STG共通関数:弾 { "DeleteShotAll", StgStageScript::Func_DeleteShotAll, 2 }, { "DeleteShotInCircle", StgStageScript::Func_DeleteShotInCircle, 5 }, + { "DeleteShotInRegularPolygon", StgStageScript::Func_DeleteShotInRegularPolygon, 7 }, { "CreateShotA1", StgStageScript::Func_CreateShotA1, 6 }, { "CreateShotPA1", StgStageScript::Func_CreateShotPA1, 8 }, { "CreateShotA2", StgStageScript::Func_CreateShotA2, 8 }, //Deprecated, exists for compatibility @@ -1439,9 +1440,9 @@ gstd::value StgStageScript::Func_DeleteShotAll(gstd::script_machine* machine, in case TYPE_ITEM:typeTo = StgShotManager::TO_TYPE_ITEM; break; } - stageController->GetShotManager()->DeleteInCircle(typeDel, typeTo, StgShotObject::OWNER_ENEMY, 0, 0, nullptr); + size_t res = stageController->GetShotManager()->DeleteInCircle(typeDel, typeTo, StgShotObject::OWNER_ENEMY, 0, 0, nullptr); - return value(); + return script->CreateIntValue(res); } gstd::value StgStageScript::Func_DeleteShotInCircle(gstd::script_machine* machine, int argc, const gstd::value* argv) { StgStageScript* script = (StgStageScript*)machine->data; @@ -1465,9 +1466,37 @@ gstd::value StgStageScript::Func_DeleteShotInCircle(gstd::script_machine* machin case TYPE_ITEM:typeTo = StgShotManager::TO_TYPE_ITEM; break; } - stageController->GetShotManager()->DeleteInCircle(typeDel, typeTo, StgShotObject::OWNER_ENEMY, posX, posY, &radius); + size_t res = stageController->GetShotManager()->DeleteInCircle(typeDel, typeTo, StgShotObject::OWNER_ENEMY, posX, posY, &radius); - return value(); + return script->CreateIntValue(res); +} +gstd::value StgStageScript::Func_DeleteShotInRegularPolygon(gstd::script_machine* machine, int argc, const gstd::value* argv) { + StgStageScript* script = (StgStageScript*)machine->data; + StgStageController* stageController = script->stageController_; + + int typeDel = argv[0].as_int(); + int typeTo = argv[1].as_int(); + int posX = argv[2].as_real(); + int posY = argv[3].as_real(); + int radius = argv[4].as_real(); + int edges = argv[5].as_int(); + double angle = argv[6].as_real(); + + switch (typeDel) { + case TYPE_ALL:typeDel = StgShotManager::DEL_TYPE_ALL; break; + case TYPE_SHOT:typeDel = StgShotManager::DEL_TYPE_SHOT; break; + case TYPE_CHILD:typeDel = StgShotManager::DEL_TYPE_CHILD; break; + } + + switch (typeTo) { + case TYPE_IMMEDIATE:typeTo = StgShotManager::TO_TYPE_IMMEDIATE; break; + case TYPE_FADE:typeTo = StgShotManager::TO_TYPE_FADE; break; + case TYPE_ITEM:typeTo = StgShotManager::TO_TYPE_ITEM; break; + } + + size_t res = stageController->GetShotManager()->DeleteInRegularPolygon(typeDel, typeTo, StgShotObject::OWNER_ENEMY, posX, posY, &radius, edges, angle); + + return script->CreateIntValue(res); } gstd::value StgStageScript::Func_CreateShotA1(gstd::script_machine* machine, int argc, const gstd::value* argv) { StgStageScript* script = (StgStageScript*)machine->data; diff --git a/source/TouhouDanmakufu/Common/StgStageScript.hpp b/source/TouhouDanmakufu/Common/StgStageScript.hpp index c28d1cc6..a7c1e093 100644 --- a/source/TouhouDanmakufu/Common/StgStageScript.hpp +++ b/source/TouhouDanmakufu/Common/StgStageScript.hpp @@ -260,6 +260,7 @@ class StgStageScript : public StgControlScript { //STG共通関数:弾 static gstd::value Func_DeleteShotAll(gstd::script_machine* machine, int argc, const gstd::value* argv); static gstd::value Func_DeleteShotInCircle(gstd::script_machine* machine, int argc, const gstd::value* argv); + static gstd::value Func_DeleteShotInRegularPolygon(gstd::script_machine* machine, int argc, const gstd::value* argv); static gstd::value Func_CreateShotA1(gstd::script_machine* machine, int argc, const gstd::value* argv); static gstd::value Func_CreateShotPA1(gstd::script_machine* machine, int argc, const gstd::value* argv); static gstd::value Func_CreateShotA2(gstd::script_machine* machine, int argc, const gstd::value* argv); diff --git a/source/TouhouDanmakufu/DnhExecutor/th_dnh_poup.ico b/source/TouhouDanmakufu/DnhExecutor/th_dnh_poup.ico new file mode 100644 index 0000000000000000000000000000000000000000..b01b11ca9111689b2d403d13400b80474b35823d GIT binary patch literal 16958 zcmeI3FN{@36vi(KQGsYuBz1rymAIvw^Y@R^xx7_ zm9{UdeP37A7in)_!cxKy2|H5#Xj`hP&p&f`h5rAYIWDGBSRUi&R0_Y0v64#R?ideJ zDLl`xnvP5OE7cD{e($SvpTK(_r+q>17HH3JX6wSD*W97OZ7tAdFpu%&*eS5my&knaX|dyKV=>V+nqnUpclTQC;Fl{ zKHv*J;hX!rbEjDeyLOogyLUUZ-?e$HM7)%)_1uu>g_Y5zpFWuhZ{9eX`CxPTm-v+G zqQAUvoF2;G^ErI!2W`Hir*f~5`(5@KU-#@Wt7HFuvl1F)S}KSo;vv5*#vG5+=K1T1 zg8*N2;5d)_jpdIv=$E%&$I_sUzs|b`)ADcQo%eI^-}pdDduc!AS6`V42M=~b?JixT zd-IKVsnq-P&BvY9ygKQk9JVqB^MgL$H->+SyXuDUFKN&qpDMcfljn)|Zr*hdw2$BL zICRLYj>Ct|gri5h!F4LzHfh59Xh++%)W^J0F(44{#KG3#Pn%1nxR>~M#XvnDIQJ5N zbYXla&rkMu^hST$gV*?n&!VV(G z!RGUS`O>+U_@nFM_)q6M`qLi#K7QOxh;jH>+CR272e@;`OnCRs!F(+D?&eK1p{kCI z;q!Celk1V+pC8A(Wp&&({3Z^z7XSDjT_68aK5z}%_*3umc-=4L{k_e1;=tDqF4}S+{QLNyIg_)CIW+vsF;L>)JfUqri9|?!tu&4&9@eq@DFRC_OL6gIDR9!q(w04bYJ?^kO{l z_;>A2tj()S{1pr2b9lD#&-*<(Hv7Ae6I_qKdHLakSsgcSm-_87>-*Bce|va5 zn%mUpH?+IXxxUZ&t-T&YS@4O5Ra{lP>_N`ftk`D0X9LJQjKlm+{zjW&7pX(9FIp?-xbZX;$ z_Nea%9V7_N@G0C{l{;{0gh+oAAKb>p{}k4{Hf!Za-;dvFVJb07=Z7P zlKvC(0^;vc@=>@q#_d$%d8x#IU(aD3g8svJ22cDZ4^R((-M3L1lyxfcmj-pzb(lZ@ z&DS9BLv`-#qXGQA|L6WQ55VUk{)@lHk%$BB=WUuirvLU`H=px$4Hn0LS`El)D(~NS zxQ3Hj%~yj-{>)RE2d=08qcKub)48vCseW=gkEF{&D`wdEFX_!@Y!9=LtRhyD#)OnXVJWWg6~B()EJt-8cWA zCjZy_|0Ms%qwgK@SAXx;K>P*x5f5GbrNL0l#y^jL#!GZ$JdJs&fB&9`zPPG_|LJg#cDlvsQ<+MYPx52ZJcJ@r=3mzeZ7x$(0TDE4m`f9 z)TR<*tz@h4r#}q!Kl0#%#PPxCH(&KV)@^xSnSW(huGk3hKYiLvhN{~u`=iZyzsLV>{&D{_oa@)ZyIywX#9ud< zzt5kT55ZUSV)mnKYj;4^Mpe`Adug#6jNPwstPEJ~V(g zWm~>mKY#Q*JMX0(v@0)j zUEq_KT$kU^G4J8Mv?J#AeZ2A6|86n