aiming cone attacks like fire-breath in any direction

All development conversation and discussion takes place here

Moderator: Moderator

Post Reply
Message
Author
tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

aiming cone attacks like fire-breath in any direction

#1 Post by tiger_eye »

Being able to aim cone attacks in any direction is a beautiful thing! No longer will you need to choose one of eight directions if you follow these simple steps :)

First, define a new function in "src/fov/fov.h"

Code: Select all

void fov_beam_any_angle(fov_settings_type *settings, void *map, void *source,
                        int source_x, int source_y, unsigned radius,
                        float dir_angle, float beam_angle
);
Second, download the attachment "fov.c-append" and append it to "src/fov/fov.c".

Third, define it's usage in "src/fov.c"

Code: Select all

static int lua_fov_calc_beam_any_angle(lua_State *L)
{
        int x = luaL_checknumber(L, 1);
        int y = luaL_checknumber(L, 2);
        int w = luaL_checknumber(L, 3);
        int h = luaL_checknumber(L, 4);
        int radius = luaL_checknumber(L, 5);
        float dir_angle = luaL_checknumber(L, 6);
        float beam_angle = luaL_checknumber(L, 7);
        struct lua_fov fov;
        if (lua_isuserdata(L, 10))
        {
                fov.cache = (struct lua_fovcache*)auxiliar_checkclass(L, "fov{cache}", 10);
                fov.cache_ref = luaL_ref(L, LUA_REGISTRYINDEX);
        }
        else
        {
                lua_pop(L, 1);
                fov.cache_ref = LUA_NOREF;
                fov.cache = NULL;
        }
        fov.L = L;
        fov.apply_ref = luaL_ref(L, LUA_REGISTRYINDEX);
        fov.opaque_ref = luaL_ref(L, LUA_REGISTRYINDEX);
        fov.cache = NULL;
        fov.w = w;
        fov.h = h;

        fov_settings_init(&(fov.fov_settings));
        fov_settings_set_opacity_test_function(&(fov.fov_settings), map_opaque);
        fov_settings_set_apply_lighting_function(&(fov.fov_settings), map_seen);
        fov_beam_any_angle(&(fov.fov_settings), &fov, NULL, x, y, radius+1, dir_angle, beam_angle);
        map_seen(&fov, x, y, 0, 0, radius, NULL);
        fov_settings_free(&(fov.fov_settings));

        luaL_unref(L, LUA_REGISTRYINDEX, fov.apply_ref);
        luaL_unref(L, LUA_REGISTRYINDEX, fov.opaque_ref);
        if (fov.cache_ref != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, fov.cache_ref);

        return 0;
}
and don't forget to define the Lua binding in "fovlib" at the end of the file "src/fov.c":

Code: Select all

{"calc_beam_any_angle", lua_fov_calc_beam_any_angle},
After this, you can call "calc_beam_any_angle" wherever you wish in lua! For example, for cone attacks, change line 136 in "game/engines/default/engine/Target.lua" from

Code: Select all

initial_dir,
to

Code: Select all

math.deg(math.atan2(self.target.y - self.source_actor.y, self.target.x - self.source_actor.x))
and that should do it! Oh, except for the graphics...
Attachments
fov.c-append.txt
(7.05 KiB) Downloaded 137 times

tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

Re: aiming cone attacks like fire-breath in any direction

#2 Post by tiger_eye »

...and of course changing line 130 in "game/engines/default/engine/Target.lua" from

Code: Select all

core.fov.calc_beam(

Code: Select all

core.fov.calc_beam_any_angle(

yufra
Perspiring Physicist
Posts: 1332
Joined: Tue Jul 13, 2010 2:53 pm

Re: aiming cone attacks like fire-breath in any direction

#3 Post by yufra »

Here is a complete patch with the source changes as well as targeting/projection updates. There is no projectile+cone so I haven't tested that yet.

EDIT: Updated patch later in the thread.
Last edited by yufra on Tue Mar 01, 2011 10:55 pm, edited 1 time in total.
<DarkGod> lets say it's intended

tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

Re: aiming cone attacks like fire-breath in any direction

#4 Post by tiger_eye »

Thanks, yufra.

I modified "src/fov/fov.c:fov_beam_any_angle(...)" so "angle_begin" can't be negative when it's used. I don't know if this is problem or not (it probably is), but I don't want to find out for sure. Heh, this is what happens when I take shortcuts! Sorry for not having this done properly the first time...

change

Code: Select all

    /* Calculate the angles as a percentage of 45 degrees *
     * Note: use "-dir_angle" because I got the order of octants in BEAM_ANY.. backwards below */
    angle_begin = (-dir_angle - 0.5*beam_angle) / 45.0f;
    angle_end = (-dir_angle + 0.5*beam_angle) / 45.0f;
    if (angle_begin < 0.0f) {
        angle_begin += 8.0f;
        angle_end += 8.0f;
    }

    if (1.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(0.0f, pmn, mpy, mmy, mmn, mpn, pmy, ppy, ppn);
    } else if (2.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(1.0f, mpy, mmy, mmn, mpn, pmy, ppy, ppn, pmn);
    } else if (3.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(2.0f, mmy, mmn, mpn, pmy, ppy, ppn, pmn, mpy);
    } else if (4.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(3.0f, mmn, mpn, pmy, ppy, ppn, pmn, mpy, mmy);
    } else if (5.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(4.0f, mpn, pmy, ppy, ppn, pmn, mpy, mmy, mmn);
    } else if (6.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(5.0f, pmy, ppy, ppn, pmn, mpy, mmy, mmn, mpn);
    } else if (7.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(6.0f, ppy, ppn, pmn, mpy, mmy, mmn, mpn, pmy);
    } else if (8.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(7.0f, ppn, pmn, mpy, mmy, mmn, mpn, pmy, ppy);
    }
}
to

Code: Select all

    /* Calculate the angles as a percentage of 45 degrees */
    angle_begin = (dir_angle - 0.5*beam_angle) / 45.0f;
    angle_end = (dir_angle + 0.5*beam_angle) / 45.0f;
    if (angle_begin < 0.0f) {
        angle_begin += 8.0f;
        angle_end += 8.0f;
    }

    if (1.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(0.0f, ppn, ppy, pmy, mpn, mmn, mmy, mpy, pmn);
    } else if (2.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(1.0f, ppy, pmy, mpn, mmn, mmy, mpy, pmn, ppn);
    } else if (3.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(2.0f, pmy, mpn, mmn, mmy, mpy, pmn, ppn, ppy);
    } else if (4.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(3.0f, mpn, mmn, mmy, mpy, pmn, ppn, ppy, pmy);
    } else if (5.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(4.0f, mmn, mmy, mpy, pmn, ppn, ppy, pmy, mpn);
    } else if (6.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(5.0f, mmy, mpy, pmn, ppn, ppy, pmy, mpn, mmn);
    } else if (7.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION(6.0f, mpy, pmn, ppn, ppy, pmy, mpn, mmn, mmy);
    } else if (8.0f - angle_begin > FLT_EPSILON) {
        BEAM_ANY_DIRECTION_DIAG(7.0f, pmn, ppn, ppy, pmy, mpn, mmn, mmy, mpy);
    }
}

yufra
Perspiring Physicist
Posts: 1332
Joined: Tue Jul 13, 2010 2:53 pm

Re: aiming cone attacks like fire-breath in any direction

#5 Post by yufra »

Updated patch attached.
Attachments
any_direction_cone_and_a_fix.txt
(11.63 KiB) Downloaded 125 times
<DarkGod> lets say it's intended

darkgod
Master of Eyal
Posts: 10750
Joined: Wed Jul 24, 2002 9:26 pm
Location: Angolwen
Contact:

Re: aiming cone attacks like fire-breath in any direction

#6 Post by darkgod »

Super neat!
Added
[tome] joylove: You can't just release an expansion like one would release a Kraken XD
--
[tome] phantomfrettchen: your ability not to tease anyone is simply stunning ;)

tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

Re: aiming cone attacks like fire-breath in any direction

#7 Post by tiger_eye »

I finally tested this around walls and such, and it looks like the following change is needed (beginning at "if (dy0 > 0)"):

Code: Select all

                                                                                                \
        if (!apply_diag && dy1 == dx) {                                                         \
            /* We do diagonal lines on every second octant, so they don't get done twice. */    \
            --dy1;                                                                              \
                                                                                                \
            /* But, we still need to check if we can see past it if the slopes are similar */   \
            if (dy1 < dy0) {                                                                    \
                if (settings->opaque(data->map, x, y)) {                                        \
                    return;                                                                     \
                }                                                                               \
                prev_blocked = 0;                                                               \
            }                                                                                   \
        }                                                                                       \
                                                                                                \
        /* we also need to check if the previous spot is blocked */                             \
        if (dy0 > 0) {                                                                          \
            ry -= 1;                                                                            \
            if (settings->opaque(data->map, x, y)) {                                            \
                prev_blocked = 1;                                                               \
            }                                                                                   \
            ry += 1;                                                                            \
        }                                                                                       \
                                                                                                \

tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

Re: aiming cone attacks like fire-breath in any direction

#8 Post by tiger_eye »

Before
before.png
before.png (149.42 KiB) Viewed 1918 times
After
after.png
after.png (141.6 KiB) Viewed 1918 times

tiger_eye
Perspiring Physicist
Posts: 889
Joined: Thu Feb 17, 2011 5:20 am

Re: aiming cone attacks like fire-breath in any direction

#9 Post by tiger_eye »

patch attached
Attachments
cone_edge_fix.txt
(1.62 KiB) Downloaded 120 times

Post Reply