1. Hey Guest, is it this your first time on the forums?

    Visit the Beginner's Box

    Introduce yourself, read some of the ins and outs of the community, access to useful links and information.

    Dismiss Notice

Classic Notch Climbing?

Discussion in 'Modding Help' started by Shadowblitz16, Mar 25, 2017.

  1. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    just a few questions regarding the notch climbing that you could do kag classic.
    what is the easiest and best way to re implement this?

    if you don't know what I'm talking about its where players could climb one block gaps in walls and/or hangout there if they wanted.
     
    Sytoplasma likes this.
  2. Pirate-Rob

    Pirate-Rob Haxor Staff Alumni Tester

    Messages:
    270
    Wall notch climbing is almost possible, you probably just need to tweak the wall run code a bit to make it work.
     
    Sytoplasma likes this.
  3. epsilon

    epsilon Assonist THD Team Forum Moderator Donator Tester

    Messages:
    506
    Well, even though this post is in the modding section, it is still possible to do notch climbing but it requires a bit more setup.
    [​IMG]
    As this GIF demonstrates you are able to notch climb mostly consistently if you use doors and platforms. You can use any door, wood or stone, and the platform needs to be facing the side which you run up on. I generally put 3 blocks between each segment since that usually works. The order is as follows:
    :castle_wall:
    :castle_wall:
    :castle_wall:
    :bridge:
    :door:
    :castle_wall:
    :castle_wall:
    :castle_wall:
    :bridge:
    :door:
    :castle_wall:
    :castle_wall:
    :castle_wall:
    :blank::blank::migrant:
    Make sure you put the door below the platform otherwise it won't work! iirc you don't even need to put the doors there but this only allows your team to run up the wall, just like when you put doors in the notches in classic.
     
  4. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    @Pirate-Rob I have no idea how to achieve something like this. as I am not familiar enough with the modding api.
    could you explain more on what to change?

    its looks like it has something to do with the speed the characters climb walls but I'm not sure about that.
     
  5. makmoud98

    makmoud98 You are already DEAD Forum Moderator Staff Alumni Tester

    Messages:
    586
    start reading runnermovement.as from line 218 (ideally you should read and interpret the entire thing)
     
  6. Pirate-Rob

    Pirate-Rob Haxor Staff Alumni Tester

    Messages:
    270
    Tbh, I'm not sure what to change, I'd have to figure it out. So just do what Makmoud said and see if you can get it right.
     
  7. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    I'm guessing this?
    Code:
    if (!surface_above && vel.y < slidespeed &&
        ((left && surface_left && !jumpedLEFT) || (right && surface_right && !jumpedRIGHT) || set_contact)) //I'm guessing this checks if the left or right side is solid? and your pressing in that direction?
        //and possibly check if the top left section from the player is nonsolid?
    
    for example if I was wall running left..
    this would treat players a 2x2 tilespace and check if the top left is empty and the bottom left is solid and if so then allow the player to wall run?

    I'm just not sure how to do a upper tile check
    --- Double Post Merged, Mar 26, 2017, Original Post Date: Mar 26, 2017 ---

    EDIT:
    so I am starting to understand this I think
    this is my code currently.
    Code:
    //check solid tiles
            const f32 ts = map.tilesize;
            const f32 y_ts = ts * 0.2f;
            const f32 x_ts = ts * 1.2f;
    
            //Top left check?
            bool surface_topleft = map.isTileSolid(pos + Vec2f(-x_ts, y_ts - map.tilesize));
            //Bottom left check?
            bool surface_bottomleft = map.isTileSolid(pos + Vec2f(-x_ts, y_ts));
    
            bool surface_left = (surface_topleft || !surface_topleft) && surface_bottomleft;
            if (!surface_left)
            {
                surface_left = checkForSolidMapBlob(map, pos + Vec2f(-x_ts, y_ts - map.tilesize)) ||
                              checkForSolidMapBlob(map, pos + Vec2f(-x_ts, y_ts));
            }
            //Top right check?
            bool surface_topright = map.isTileSolid(pos + Vec2f(x_ts, y_ts - map.tilesize));
            //Bottom right check?
            bool surface_bottomright = map.isTileSolid(pos + Vec2f(x_ts, y_ts));
         
         
            bool surface_right = (surface_topright || !surface_topright) && surface_bottomright;
            if (!surface_right)
            {
                surface_right = checkForSolidMapBlob(map, pos + Vec2f(x_ts, y_ts - map.tilesize)) ||
                               checkForSolidMapBlob(map, pos + Vec2f(x_ts, y_ts));
            }
    
            //not checking blobs for this - perf
            bool surface_above = map.isTileSolid(pos + Vec2f(y_ts, -x_ts)) || map.isTileSolid(pos + Vec2f(-y_ts, -x_ts));
            bool surface_below = map.isTileSolid(pos + Vec2f(y_ts, x_ts)) || map.isTileSolid(pos + Vec2f(-y_ts, x_ts));
    
            bool surface = surface_left || surface_right;
    
            const f32 slidespeed = 2.45f;
    
            //wall jumping/running
            if (up && surface &&                                     //only on surface
                   moveVars.walljumped_side != Walljump::BOTH &&        //do nothing if jammed
                   !(left && right) &&                                    //do nothing if pressing both sides
                   !onground)
            {
                bool wasNONE = (moveVars.walljumped_side == Walljump::NONE);
    
                bool jumpedLEFT = (moveVars.walljumped_side == Walljump::JUMPED_LEFT);
                bool jumpedRIGHT = (moveVars.walljumped_side == Walljump::JUMPED_RIGHT);
    
                bool dust = false;
    
                if (moveVars.jumpCount > 5) //wait some time to be properly in the air
                {
                    //set contact point
                    bool set_contact = false;
                    if  (left && surface_left && (moveVars.walljumped_side == Walljump::RIGHT || jumpedRIGHT || wasNONE))
                    {
                        //Test for Notch Climbing
                        if (left && surface_topleft) moveVars.wallrun_current = pos.y + 16.0f;
                        moveVars.walljumped_side = Walljump::LEFT;
                        moveVars.wallrun_start = pos.y;
                        moveVars.wallrun_current = pos.y + 1.0f;
                        set_contact = true;
                    }
                    if  (right && surface_right && (moveVars.walljumped_side == Walljump::LEFT || jumpedLEFT || wasNONE))
                    {
                        //Test for Notch Climbing
                        if (right && surface_topright) moveVars.wallrun_current = pos.y + 16.0f;
                        moveVars.walljumped_side = Walljump::RIGHT;
                        moveVars.wallrun_start = pos.y;
                        moveVars.wallrun_current = pos.y + 1.0f;
                        set_contact = true;
                    }
    
                    //wallrun
                    if (!surface_above && vel.y < slidespeed &&
                            ((left && surface_left && !jumpedLEFT) || (right && surface_right && !jumpedRIGHT) || set_contact))
     
                    {
                        //within range
                        if (set_contact ||
                               (pos.y - 1.0f < moveVars.wallrun_current &&
                                pos.y + 1.0f > moveVars.wallrun_start - map.tilesize * moveVars.wallrun_length))
                        {
                            moveVars.wallrun_current = Maths::Min(pos.y - 1.0f, moveVars.wallrun_current - 1.0f);
    
                            moveVars.walljumped = true;
                            if (set_contact || getGameTime() % 5 == 0)
                            {
                                dust = true;
    
                                f32 wallrun_speed = moveVars.jumpMaxVel * 1.2f;
    
                                if (vel.y > -wallrun_speed || set_contact)
                                {
                                    vel.Set(0, -wallrun_speed);
                                    blob.setVelocity(vel);
                                }
    
                                if (!set_contact)
                                {
                                    blob.getSprite().PlayRandomSound("/StoneJump");
                                }
                            }
                        }
                        else
                        {
                            moveVars.walljumped = false;
                        }
                    }
                    //walljump
                    else if (vel.y < slidespeed &&
                            ((left && surface_right) || (right && surface_left)) &&
                            !surface_below && !jumpedLEFT && !jumpedRIGHT)
                    {
                        f32 walljumpforce = 4.0f;
                        vel.Set(surface_right ? -walljumpforce : walljumpforce, -2.0f);
                        blob.setVelocity(vel);
    
                        dust = true;
    
                        moveVars.jumpCount = 0;
    
                        if (right)
                        {
                            moveVars.walljumped_side = Walljump::JUMPED_LEFT;
                        }
                        else
                        {
                            moveVars.walljumped_side = Walljump::JUMPED_RIGHT;
                        }
                    }
                }
    
                if (dust)
                {
                    Vec2f dust_pos = (Vec2f(right ? 4.0f : -4.0f, 0.0f) + pos);
                    MakeDustParticle(dust_pos, "Smoke.png");
                }
            }
            else
            {
                moveVars.walljumped = false;
            }
    
    The problem is that I the player is not being flung up when the surface_topleft or surface_topright is empty it should be moving my player 16.0 in the y direction
     
  8. Geti

    Geti Please avoid PMing me (poke a mod instead) THD Team Administrator Global Moderator

    Messages:
    3,730
    Classic notch climbing is actually just a result of the movement physics of classic - when you "fit into" the notch, you touch a downwards surface, your character thinks it's on the ground, and it can jump again.

    If you're keeping the existing wallrunning (not re-creating classic exactly, like that classic mod was trying to do), you could just detect when the character is in a notch and reset the wallrun counter, letting you run infinitely up notched walls.
    [​IMG]
    You can detect being "in" a notch by checking the tile one up and down from the centre of the player object, to each side, for solidity. Just detect that state and either allow jumping or wallrunning and you'll have notch climbing.
     
    ParaLogia likes this.
  9. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    ok so something like this?

    Code:
            bool notch_left = map.isTileSolid(pos + Vec2f(-x_ts, y_ts - map.tilesize)) &&
                               map.isTileSolid(pos + Vec2f(-x_ts, y_ts + map.tilesize));
    
    Edit: probably check for the blobs too.
     
  10. Geti

    Geti Please avoid PMing me (poke a mod instead) THD Team Administrator Global Moderator

    Messages:
    3,730
    Something like that, but uh you might want to avoid reusing the x_ts and y_ts variables there - they're not equal to a tilesize and have separate scaling factors for different reasons than notch detection. You'd be better off defining your own variables for the offsets, like so:
    Code:
    //notch offset
    //(do your scaling here)
    f32 notch_x_scale = 1.0f;
    f32 notch_y_scale = 1.0f;
    Vec2f n_o(map.tilesize * notch_x_scale, map.tilesize * notch_y_scale);
    
    bool notch_left = map.isTileSolid(pos + Vec2f(-n_o.x, n_o.y)) &&
                        map.isTileSolid(pos + Vec2f(-n_o.x, -n_o.y));
    
    bool notch_right = map.isTileSolid(pos + Vec2f(n_o.x, n_o.y)) &&
                        map.isTileSolid(pos + Vec2f(n_o.x, -n_o.y));
     
  11. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    oh ok thankyou I wasn't sure what the ts things were I was just going along with them.


    EDIT: Wow it works thankyou Geti!
    --- Double Post Merged, Mar 27, 2017, Original Post Date: Mar 27, 2017 ---
    Sadly I found some bugs.

    just checking for collisions on top and bottom doesn't work since I'm not checking for the middle to be nonsolid
    however when I checked if the middle was nonsolid its gave me problems with the team doors being in the notch...
    instead of the opposite teams doors blocking the player from notch climbing it boosted them significantly.
    I am currently making a script to hold this game function this is it..
    Code:
    
    #include "RunnerCommon.as"
    #include "MakeDustParticle.as";
    #include "FallDamageCommon.as";
    #include "Knocked.as";
    #include "RunnerMovement.as"
    
    
    void onInit(CMovement@ this)
    {
        this.getCurrentScript().removeIfTag = "dead";
        this.getCurrentScript().runFlags |= Script::tick_not_attached;
    }
    
    
    void onTick(CMovement@ this)
    {
        CBlob@ blob = this.getBlob();
        RunnerMoveVars@ moveVars;
        if (!blob.get("moveVars", @moveVars))
        {
            return;
        }
       
        CMap@ map = getMap();
       
        CShape@ shape = blob.getShape();
        const f32 vellen = shape.vellen;
       
        const bool is_client = getNet().isClient();
    
        const bool left        = blob.isKeyPressed(key_left);
        const bool right    = blob.isKeyPressed(key_right);
        const bool up        = blob.isKeyPressed(key_up);
        const bool down        = blob.isKeyPressed(key_down);
    
        const bool isknocked = isKnocked(blob);
        const bool isgrounded = blob.isOnGround() || blob.isOnLadder();
        const bool isclimbing = blob.isOnLadder();
        const bool isswimming = blob.isInWater();
    
        f32 notch_x_scale = 1.0f;
        f32 notch_y_scale = 1.0f;
        Vec2f notch_offset(map.tilesize * notch_x_scale, map.tilesize * notch_y_scale);
       
        if ((!isswimming) && (!isclimbing) && (!isknocked))
        {
            //////////////////////////////////////////////////////////////////////////////////////
            //LEFT
            //////////////////////////////////////////////////////////////////////////////////////
           
            //Wall Check
            bool surface_left =  (map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
                                 map.isTileSolid(pos + Vec2f(-notch_offset.x, -notch_offset.y)));                 
            //Notch Check
            bool notch_left   = (!map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y * 0)));
                                 
            //No Tile Collision Check for Blob Collision
            if (!surface_left)
            {
                //Notch Check for blobs
                surface_left = (checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
                                checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, -notch_offset.y)));
            }       
           
            //Check for Overall Collision
            if (surface_left)
            {
                notch_left = (!map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y * 0)));
                if (!notch_left) 
                notch_left = (!checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, 0)));
            }
           
            //////////////////////////////////////////////////////////////////////////////////////
            //RIGHT
            //////////////////////////////////////////////////////////////////////////////////////
           
            //Wall Check
            bool surface_right =  map.isTileSolid(pos + Vec2f(notch_offset.x,  notch_offset.y)) &&
                                 map.isTileSolid(pos + Vec2f(notch_offset.x, -notch_offset.y));                 
            //Notch Check
            bool notch_right   = false;
                                 
            //No Tile Collision Check for Blob Collision
            if (!surface_right)
            {
                //Notch Check for blobs
                surface_right = checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x,  notch_offset.y)) &&
                              checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, -notch_offset.y));
            }       
           
            //Check for Overall Collision
            if (surface_right)
            {
                notch_right = !map.isTileSolid(pos + Vec2f(notch_offset.x,  notch_offset.y * 0));
                if (!notch_right) 
                notch_right = !checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, 0));
            }
           
            //////////////////////////////////////////////////////////////////////////////////////
            //ACTION
            //////////////////////////////////////////////////////////////////////////////////////       
            if ((left && notch_left) || (right && notch_right))
            {
                moveVars.walljumped_side = Walljump::NONE;
                moveVars.wallrun_start = pos.y;
                moveVars.wallrun_current = pos.y;
                moveVars.fallCount = -1;
            }
        }
    }
    
    however I get a ton of errors that I don't understand.
    here they are..
    Code:
    [07:05:42] Script: A function with the same name and parameters already exists
    [07:05:42]         [line 8 char 1] void onInit(CMovement@ this)
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerMovement.as'
    [07:05:42] Script: A function with the same name and parameters already exists
    [07:05:42]         [line 14 char 1] void onTick(CMovement@ this)
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerMovement.as'
    [07:05:42] Script: Compiling void onTick(CMovement@ this)
    [07:05:42] Script: 'pos' is not declared
    [07:05:42]         [line 53 char 42]                    bool surface_left =  (map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No conversion from 'Vec2f' to math type available.
    [07:05:42]         [line 54 char 31]                                                              map.isTileSolid(pos + Vec2f(-notch_offset.x, -notch_offset.y)));
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No conversion from 'int' to 'bool' available.
    [07:05:42]         [line 53 char 89]                    bool surface_left =  (map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No conversion from 'Vec2f' to math type available.
    [07:05:42]         [line 56 char 46]                    bool notch_left   = (!map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y * 0)));
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No conversion from 'Vec2f' to math type available.
    [07:05:42]         [line 62 char 51]                            surface_left = (checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No matching signatures to 'checkForSolidMapBlob(CMap@&, const int)'
    [07:05:42]         [line 62 char 21]                            surface_left = (checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: Candidates are:
    [07:05:42] Script: bool checkForSolidMapBlob(CMap@ map, Vec2f pos)
    [07:05:42] Script: No conversion from 'Vec2f' to math type available.
    [07:05:42]         [line 63 char 42]                                                        checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, -notch_offset.y)));
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No matching signatures to 'checkForSolidMapBlob(CMap@&, const int)'
    [07:05:42]         [line 63 char 12]                                                        checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, -notch_offset.y)));
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: Candidates are:
    [07:05:42] Script: bool checkForSolidMapBlob(CMap@ map, Vec2f pos)
    [07:05:42] Script: No conversion from 'int' to 'bool' available.
    [07:05:42]         [line 62 char 94]                            surface_left = (checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x,  notch_offset.y)) &&
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No conversion from 'Vec2f' to math type available.
    [07:05:42]         [line 69 char 40]                            notch_left = (!map.isTileSolid(pos + Vec2f(-notch_offset.x,  notch_offset.y * 0)));
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No conversion from 'Vec2f' to math type available.
    [07:05:42]         [line 71 char 50]                            notch_left = (!checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, 0)));
    [07:05:42]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:42] Script: No matching signatures to 'checkForSolidMapBlob(CMap@&, const int)'
    [07:05:42]         [line 71 char 20]                            notch_left = (!checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, 0)));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: Candidates are:
    [07:05:43] Script: bool checkForSolidMapBlob(CMap@ map, Vec2f pos)
    [07:05:43] Script: Illegal operation on this datatype
    [07:05:43]         [line 71 char 19]                            notch_left = (!checkForSolidMapBlob(map, pos + Vec2f(-notch_offset.x, 0)));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No conversion from 'Vec2f' to math type available.
    [07:05:43]         [line 79 char 46]                    bool surface_right =  map.isTileSolid(pos + Vec2f(notch_offset.x,  notch_offset.y)) &&
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No conversion from 'Vec2f' to math type available.
    [07:05:43]         [line 80 char 31]                                                              map.isTileSolid(pos + Vec2f(notch_offset.x, -notch_offset.y));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No conversion from 'Vec2f' to math type available.
    [07:05:43]         [line 88 char 51]                            surface_right = checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x,  notch_offset.y)) &&
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No matching signatures to 'checkForSolidMapBlob(CMap@&, const int)'
    [07:05:43]         [line 88 char 21]                            surface_right = checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x,  notch_offset.y)) &&
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: Candidates are:
    [07:05:43] Script: bool checkForSolidMapBlob(CMap@ map, Vec2f pos)
    [07:05:43] Script: No conversion from 'Vec2f' to math type available.
    [07:05:43]         [line 89 char 41]                                                       checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, -notch_offset.y));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No matching signatures to 'checkForSolidMapBlob(CMap@&, const int)'
    [07:05:43]         [line 89 char 11]                                                       checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, -notch_offset.y));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: Candidates are:
    [07:05:43] Script: bool checkForSolidMapBlob(CMap@ map, Vec2f pos)
    [07:05:43] Script: No conversion from 'int' to 'bool' available.
    [07:05:43]         [line 88 char 93]                            surface_right = checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x,  notch_offset.y)) &&
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No conversion from 'Vec2f' to math type available.
    [07:05:43]         [line 95 char 40]                            notch_right = !map.isTileSolid(pos + Vec2f(notch_offset.x,  notch_offset.y * 0));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No conversion from 'Vec2f' to math type available.
    [07:05:43]         [line 97 char 50]                            notch_right = !checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, 0));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: No matching signatures to 'checkForSolidMapBlob(CMap@&, const int)'
    [07:05:43]         [line 97 char 20]                            notch_right = !checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, 0));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: Candidates are:
    [07:05:43] Script: bool checkForSolidMapBlob(CMap@ map, Vec2f pos)
    [07:05:43] Script: Illegal operation on this datatype
    [07:05:43]         [line 97 char 19]                            notch_right = !checkForSolidMapBlob(map, pos + Vec2f(notch_offset.x, 0));
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: 'y' is not a member of 'int'
    [07:05:43]         [line 106 char 33]                           moveVars.wallrun_start = pos.y;
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    [07:05:43] Script: 'y' is not a member of 'int'
    [07:05:43]         [line 107 char 35]                           moveVars.wallrun_current = pos.y;
    [07:05:43]         in file '../Mods/SB16_MiniCTF/Entities/Characters/MovementScripts/RunnerNotchClimbing.as'
    
     
    Geti likes this.
  12. Geti

    Geti Please avoid PMing me (poke a mod instead) THD Team Administrator Global Moderator

    Messages:
    3,730
    You just haven't defined "pos" for whatever reason. You need to declare variables before you use them, it's probably most sensible to do so around where' you're declaring "vellen"; something like Vec2f pos = blob.getPosition();
    All of those run-on errors are from pos not being declared.

    Good catch on needing to detect an empty tile as well - that's what I get for writing code in a hurry ;)
     
  13. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    ok so I got this working but I was wondering if someone was willing to help me convert it into a portable script called RunnerNotchClimb.as?

    I would like it to be attachable to the knight.cfg.

    basicly this is the code behind it (note this is peices of it cut from RunnerMovement and will not work like this)

    Code:
            // start notch clibing stuff
            f32 notch_x_scale = 1.0f;
            f32 notch_y_scale = 1.0f;
            Vec2f n_o(map.tilesize * notch_x_scale, map.tilesize * notch_y_scale);
    
            bool notch_left  = map.isTileSolid(pos + Vec2f(-n_o.x, n_o.y)) && map.isTileSolid(pos + Vec2f(-n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f(-n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, 0.0f));
            if (!notch_left)
            {
                notch_left  = checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, n_o.y)) && checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f(-n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, 0.0f));
            }
          
            bool notch_right = map.isTileSolid(pos + Vec2f( n_o.x, n_o.y)) && map.isTileSolid(pos + Vec2f( n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f( n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f( n_o.x, 0.0f));
            if (!notch_right)
            {
                notch_right = checkForSolidMapBlob(map, pos + Vec2f( n_o.x, n_o.y)) && checkForSolidMapBlob(map, pos + Vec2f( n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f( n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f( n_o.x, 0.0f));
            }
          
                    if (left && surface_left && (moveVars.walljumped_side == Walljump::RIGHT || jumpedRIGHT || wasNONE) || notch_left)
                    {
                        moveVars.walljumped_side = Walljump::LEFT;
                        moveVars.wallrun_start = pos.y;
                        moveVars.wallrun_current = pos.y + 1.0f;
                        set_contact = true;
                    }
                    if (right && surface_right && (moveVars.walljumped_side == Walljump::LEFT || jumpedLEFT || wasNONE) || notch_right)
                    {
                        moveVars.walljumped_side = Walljump::RIGHT;
                        moveVars.wallrun_start = pos.y;
                        moveVars.wallrun_current = pos.y + 1.0f;
                        set_contact = true;
                    }
    
    sadly it spams smoke particles when I notch climb.

    anyways I tried doing this in a separate script but I need to be able to access variables from the RunnerMovement.as
     
  14. Geti

    Geti Please avoid PMing me (poke a mod instead) THD Team Administrator Global Moderator

    Messages:
    3,730
    Should be about as simple as:

    Code:
    // Runner Movement Notch Jumping
    
    #include "RunnerCommon.as"
    #include "MakeDustParticle.as";
    #include "FallDamageCommon.as";
    #include "Knocked.as";
    
    void onInit(CMovement@ this)
    {
        this.getCurrentScript().removeIfTag = "dead";
        this.getCurrentScript().runFlags |= Script::tick_not_attached;
    }
    
    void onTick(CMovement@ this)
    {
        CBlob@ blob = this.getBlob();
        RunnerMoveVars@ moveVars;
        if (!blob.get("moveVars", @moveVars))
        {
            return;
        }
    
        const bool left     = blob.isKeyPressed(key_left);
        const bool right    = blob.isKeyPressed(key_right);
        const bool up       = blob.isKeyPressed(key_up);
        const bool down     = blob.isKeyPressed(key_down);
    
        const bool isknocked = isKnocked(blob);
    
        const bool is_client = getNet().isClient();
    
        CMap@ map = blob.getMap();
        Vec2f vel = blob.getVelocity();
        Vec2f pos = blob.getPosition();
        CShape@ shape = blob.getShape();
    
        const f32 vellen = shape.vellen;
        const bool onground = blob.isOnGround() || blob.isOnLadder();
    
        // start notch clibing stuff
        f32 notch_x_scale = 1.0f;
        f32 notch_y_scale = 1.0f;
        Vec2f n_o(map.tilesize * notch_x_scale, map.tilesize * notch_y_scale);
    
        bool notch_left  = map.isTileSolid(pos + Vec2f(-n_o.x, n_o.y)) && map.isTileSolid(pos + Vec2f(-n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f(-n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, 0.0f));
        if (!notch_left)
        {
            notch_left  = checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, n_o.y)) && checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f(-n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, 0.0f));
        }
    
        bool notch_right = map.isTileSolid(pos + Vec2f( n_o.x, n_o.y)) && map.isTileSolid(pos + Vec2f( n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f( n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f( n_o.x, 0.0f));
        if (!notch_right)
        {
            notch_right = checkForSolidMapBlob(map, pos + Vec2f( n_o.x, n_o.y)) && checkForSolidMapBlob(map, pos + Vec2f( n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f( n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f( n_o.x, 0.0f));
        }
    
        if (left && surface_left && (moveVars.walljumped_side == Walljump::RIGHT || jumpedRIGHT || wasNONE) || notch_left)
        {
            moveVars.walljumped_side = Walljump::LEFT;
            moveVars.wallrun_start = pos.y;
            moveVars.wallrun_current = pos.y + 1.0f;
            set_contact = true;
        }
        if (right && surface_right && (moveVars.walljumped_side == Walljump::LEFT || jumpedLEFT || wasNONE) || notch_right)
        {
            moveVars.walljumped_side = Walljump::RIGHT;
            moveVars.wallrun_start = pos.y;
            moveVars.wallrun_current = pos.y + 1.0f;
            set_contact = true;
        }
        //TODO: probably something with set contact here?
    }
    This wont work yet but it should get the idea across - put it inside a hook, include the right files, and get the data out that you need and you should be right as rain.
    You'll need to figure out what to do at the bottom though (react to set_contact) and also pull your missing variables (jumpedLEFT and wasNONE?) into the script.
     
  15. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    ok cool thanks @Geti
    --- Double Post Merged, Jun 15, 2018, Original Post Date: Aug 22, 2017 ---
    @Geti so I finally got around to this and everything seems simple enough but the set conect thing really confuses me.
    it seems like alot of the runnerMovement code uses this var and it seems like it would be hard to replicate without just including all this stuff in the script in the first place.
    should I just add upwards velocity to the blob and call it good?


    Code:
    // Runner Movement Notch Jumping
    
    #include "RunnerCommon.as"
    #include "MakeDustParticle.as";
    #include "FallDamageCommon.as";
    #include "Knocked.as";
    
    void onInit(CMovement@ this)
    {
        this.getCurrentScript().removeIfTag = "dead";
        this.getCurrentScript().runFlags |= Script::tick_not_attached;
    }
    
    void onTick(CMovement@ this)
    {
        CBlob@ blob = this.getBlob();
        RunnerMoveVars@ moveVars;
        if (!blob.get("moveVars", @moveVars))
        {
            return;
        }
       
        bool wasNONE = (moveVars.walljumped_side == Walljump::NONE);
        bool jumpedLEFT = (moveVars.walljumped_side == Walljump::JUMPED_LEFT);
        bool jumpedRIGHT = (moveVars.walljumped_side == Walljump::JUMPED_RIGHT);
    
        const bool left     = blob.isKeyPressed(key_left);
        const bool right    = blob.isKeyPressed(key_right);
        const bool up       = blob.isKeyPressed(key_up);
        const bool down     = blob.isKeyPressed(key_down);
    
        const bool isknocked = isKnocked(blob);
    
        const bool is_client = getNet().isClient();
    
        CMap@ map = blob.getMap();
        Vec2f vel = blob.getVelocity();
        Vec2f pos = blob.getPosition();
        CShape@ shape = blob.getShape();
    
        const f32 vellen = shape.vellen;
        const bool onground = blob.isOnGround() || blob.isOnLadder();
    
        // start notch clibing stuff
        f32 notch_x_scale = 1.0f;
        f32 notch_y_scale = 1.0f;
        Vec2f n_o(map.tilesize * notch_x_scale, map.tilesize * notch_y_scale);
    
        bool notch_left  = map.isTileSolid(pos + Vec2f(-n_o.x, n_o.y)) && map.isTileSolid(pos + Vec2f(-n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f(-n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, 0.0f));
        if (!notch_left)
        {
            notch_left  = checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, n_o.y)) && checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f(-n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f(-n_o.x, 0.0f));
        }
    
        bool notch_right = map.isTileSolid(pos + Vec2f( n_o.x, n_o.y)) && map.isTileSolid(pos + Vec2f( n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f( n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f( n_o.x, 0.0f));
        if (!notch_right)
        {
            notch_right = checkForSolidMapBlob(map, pos + Vec2f( n_o.x, n_o.y)) && checkForSolidMapBlob(map, pos + Vec2f( n_o.x, -n_o.y)) && !map.isTileSolid(pos + Vec2f( n_o.x, 0.0f)) && !checkForSolidMapBlob(map, pos + Vec2f( n_o.x, 0.0f));
        }
    
        bool set_contact = false;
        if (left && notch_left && (moveVars.walljumped_side == Walljump::RIGHT || jumpedRIGHT || wasNONE))
        {
            moveVars.walljumped_side = Walljump::LEFT;
            moveVars.wallrun_start = pos.y;
            moveVars.wallrun_current = pos.y + 1.0f;
            set_contact = true;
        }
        if (right && notch_right && (moveVars.walljumped_side == Walljump::LEFT || jumpedLEFT || wasNONE))
        {
            moveVars.walljumped_side = Walljump::RIGHT;
            moveVars.wallrun_start = pos.y;
            moveVars.wallrun_current = pos.y + 1.0f;
            set_contact = true;
        }
       
        if (set_contact)
        {
            blob.setVelocity(blob.getVelocity() + Vec2f(0, -1));
        }
    }
    
    bool checkForSolidMapBlob(CMap@ map, Vec2f pos, CBlob@ blob = null)
    {
        CBlob@ _tempBlob; CShape@ _tempShape;
        @_tempBlob = map.getBlobAtPosition(pos);
        if (_tempBlob !is null && _tempBlob.isCollidable())
        {
            @_tempShape = _tempBlob.getShape();
            if (_tempShape.isStatic())
            {
                if (_tempBlob.getName() == "wooden_platform")
                {
                    f32 angle = _tempBlob.getAngleDegrees();
                    if (angle > 180)
                        angle -= 360;
                    angle = Maths::Abs(angle);
                    if (angle < 30 || angle > 150)
                    {
                        return false;
                    }
                }
    
                if (blob !is null && !blob.doesCollideWithBlob(_tempBlob))
                {
                    return false;
                }
    
                return true;
            }
        }
    
        return false;
    }
    
    
     
    Last edited: Jun 15, 2018
    Fellere825 and Geti like this.
  16. Geti

    Geti Please avoid PMing me (poke a mod instead) THD Team Administrator Global Moderator

    Messages:
    3,730
    You're honestly better asking about this stuff in discord.

    The set_contact stuff is just to move the actual logic into a single place in case there was notches on both sides, and in case you wanted to do anything extra there like limit the speed. How you react to it is up to you. In classic it basically resulted in the velocity approximating the maximum jump upwards speed, because notching came from you being able to jump while jammed into notches.