From a4cb82b25c2ec6276afa6f98b8858b4ab7ae833a Mon Sep 17 00:00:00 2001 From: ac-stef Date: Wed, 31 May 2017 01:56:18 +0200 Subject: [PATCH] point and click to select entities pointatent 0|1 enables (1) or disables (0) pointing at entities if an entity is poiinted at during disabling, it is pinned pointatentmaxangle a specifies the required precision for pointing at entities DOCREF pointatent pointatentmaxangle --- config/menus_edit.cfg | 1 + config/resetbinds.cfg | 1 + source/src/world.cpp | 42 +++++++++++++++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/config/menus_edit.cfg b/config/menus_edit.cfg index 7f61a3df..48cee3e0 100644 --- a/config/menus_edit.cfg +++ b/config/menus_edit.cfg @@ -1242,6 +1242,7 @@ menuitemeditkeyinput [Undo geometry changes: ] undo menuitemeditkeyinput [Redo: ] redo menuitem "" -1 menuitemeditkeyinput [Pin/unpin closest entity: ] toggleclosestentpin +menuitemeditkeyinput [Point to select entity: ] editkey_pointatents menuitemeditkeyinput [Delete entity: ] editkey_delete_entity menuitemeditkeyinput [Copy entity: ] copyent menuitemeditkeyinput [Paste entity: ] pasteent diff --git a/config/resetbinds.cfg b/config/resetbinds.cfg index a8f8f52c..971eb973 100644 --- a/config/resetbinds.cfg +++ b/config/resetbinds.cfg @@ -61,6 +61,7 @@ alias editkey_tagclip_plclip [ edittagclip plclip ] alias editkey_tagclip_clip [ edittagclip clip ] alias editkey_scroll_spawns [ domodifier spawns ] alias editkey_scroll_todoents [ domodifier todoents ] +alias editkey_pointatents [ pointatent 1 ; onrelease [ pointatent 0 ] ] alias speckey_demo_gamespeeddown [ if (watchingdemo) [ if (<= $gamespeed 100) [ gamespeed (- $gamespeed 10) ] [ gamespeed (- $gamespeed 100) ]; gamespeed ] ] alias speckey_demo_gamespeedup [ if (watchingdemo) [ if (< $gamespeed 100) [ gamespeed (+ $gamespeed 10) ] [ gamespeed (+ $gamespeed 100) ]; gamespeed ] ] diff --git a/source/src/world.cpp b/source/src/world.cpp index e32d87a8..e2652a11 100644 --- a/source/src/world.cpp +++ b/source/src/world.cpp @@ -116,22 +116,47 @@ void remipmore(const block &b, int level) remip(bb, level); } -static int clentsel = 0, clenttype = NOTUSED; +static int clentsel = 0, clenttype = NOTUSED, pinnedent = -1; +bool pinnedclosestent = false, pointingatents = false; -void nextclosestent(void) { clentsel++; } +COMMANDF(nextclosestent, "", () { clentsel++; } ); void closestenttype(char *what) { clenttype = what[0] ? findtype(what) : NOTUSED; } - -COMMAND(nextclosestent, ""); COMMAND(closestenttype, "s"); -bool pinnedclosestent = false; -static int pinnedent = -1; COMMANDF(toggleclosestentpin, "", () { pinnedclosestent = ents.inrange((pinnedent = pinnedclosestent ? -1 : closestent())); }); +void pointatent(int *_on) +{ + bool on = *_on != 0; + if(pointingatents != on) + { + if(on) pinnedclosestent = false; + else if(!pinnedclosestent) + { + int n = closestent(); + if(n >= 0) pinnedent = n, pinnedclosestent = true; + } + pointingatents = on; + } +} +COMMAND(pointatent, "i"); + +FVARP(pointatentmaxangle, 0.01f, 2.0f, 180.0f); + +bool intersectangular(const vec &from, vec ray, vec ent, float maxangle, float &dist) +{ + ray.sub(from); + ent.sub(from); + float v = ent.dot(ray), e = ent.magnitude(), r = ray.magnitude(); + if(v < maxangle * e * r) return false; + dist = e; + return true; +} + int closestent() // used for delent and edit mode ent display { if(noteditmode("closestent")) return -1; @@ -141,7 +166,7 @@ int closestent() // used for delent and edit mode ent display pinnedclosestent = false; // release lock when ent is deleted } int best = -1, bcnt = 0; - float bdist = 99999; + float bdist = 99999, dist, maxangle = pointingatents ? cosf(pointatentmaxangle * RAD) : -SQRT3; loopj(3) { bcnt = 0; @@ -153,8 +178,7 @@ int closestent() // used for delent and edit mode ent display bool ice = false; loopk(eh_ents.length()) if(eh_ents[k]==e.type) ice = true; if(ice) continue; - vec v(e.x, e.y, e.z); - float dist = v.dist(camera1->o); + if(!intersectangular(camera1->o, worldpos, vec(e.x, e.y, e.z), maxangle, dist)) continue; if(j) { if(ents[best].x == e.x && ents[best].y == e.y && ents[best].z == e.z)