1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. 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

Help on Getting old archer knife code working as external script? + grapple exteral script

Discussion in 'Modding Help' started by Shadowblitz16, Aug 24, 2017.

Tags:
  1. Shadowblitz16

    Shadowblitz16 Ballista Bolt Thrower

    Messages:
    158
    can someone help me with these two scripts?

    one is the old archer knife and one is the grapple.
    they are both external scripts so players can swap them out as they please

    this is my ArcherGrapple.as https://pastebin.com/8TdjQLMx
    and this is my ArcherKnife.as https://pastebin.com/C4x7yvyZ

    the archer grapple just doesn't do anything when I click right mouse button
    the archer knife doesn't do anything but animate.

    EDIT:
    so I just compared the base ArcherLogic.as and my ArcherGrapple.as and there is nothing wrong with it there are no missing properties, no errors, it just doesn't do anything.
    --- Double Post Merged, Sep 1, 2017, Original Post Date: Aug 24, 2017 ---
    I got the knife working but the grapple refuses to work as an external script

    here is the code for it
    Code:
    
    #include "ArcherCommon.as"
    #include "ThrowCommon.as"
    #include "Knocked.as"
    #include "Hitters.as"
    #include "RunnerCommon.as"
    #include "ShieldCommon.as";
    #include "Help.as";
    #include "BombCommon.as";
    
    //TODO store key enum into variable so that the weapon can be chaged to any key
    //const input_trigger = EKEY_CODE::KEY_XBUTTON2;
    
    //TODO make grapple configurable
    //const grapple_length
    //const grapple_speed
    
    void onInit(CBlob@ this)
    {
        ArcherInfo archer;
        //Add grapple sync command
        this.addCommandID(grapple_sync_cmd);
       
        this.getCurrentScript().runFlags |= Script::tick_not_attached;
        this.getCurrentScript().removeIfTag = "dead";
    }
    
    void onTick(CBlob@ this)
    {
        ArcherInfo archer;
       
        if (!this.get("archerInfo", @archer)) return;
       
        if (getKnocked(this) > 0)
        {
            archer.grappling = false;
            archer.charge_state = 0;
            archer.charge_time = 0;
            return;
        }
        ManageGrapple(this, archer);
    }
    
    void ManageGrapple(CBlob@ this, ArcherInfo@ archer)
    {
        CSprite@ sprite = this.getSprite();
        u8 charge_state = archer.charge_state;
        Vec2f pos = this.getPosition();
    
        const bool right_click = this.isKeyJustPressed(key_action3);
        if (right_click)
        {
            // cancel charging
            if (charge_state != ArcherParams::not_aiming)
            {
                charge_state = ArcherParams::not_aiming;
                archer.charge_time = 0;
                sprite.SetEmitSoundPaused(true);
                sprite.PlaySound("PopIn.ogg");
            }
            else if (canSend(this)) //otherwise grapple
            {
                archer.grappling = true;
                archer.grapple_id = 0xffff;
                archer.grapple_pos = pos;
                archer.grapple_ratio = 1.0f; //allow fully extended
    
                Vec2f direction = this.getAimPos() - pos;
    
                //aim in direction of cursor
                f32 distance = direction.Normalize();
                if (distance > 1.0f)
                {
                    archer.grapple_vel = direction * archer_grapple_throw_speed;
                }
                else
                {
                    archer.grapple_vel = Vec2f_zero;
                }
    
                SyncGrapple(this);
            }
    
            archer.charge_state = charge_state;
        }
    
        if (archer.grappling)
        {
            //update grapple
            //TODO move to its own script?
    
            if (!this.isKeyPressed(key_action3))
            {
                if (canSend(this))
                {
                    archer.grappling = false;
                    SyncGrapple(this);
                }
            }
            else
            {
                const f32 archer_grapple_range = archer_grapple_length * archer.grapple_ratio;
                const f32 archer_grapple_force_limit = this.getMass() * archer_grapple_accel_limit;
    
                CMap@ map = this.getMap();
    
                //reel in
                //TODO: sound
                if (archer.grapple_ratio > 0.2f)
                    archer.grapple_ratio -= 1.0f / getTicksASecond();
    
                //get the force and offset vectors
                Vec2f force;
                Vec2f offset;
                f32 dist;
                {
                    force = archer.grapple_pos - this.getPosition();
                    dist = force.Normalize();
                    f32 offdist = dist - archer_grapple_range;
                    if (offdist > 0)
                    {
                        offset = force * Maths::Min(8.0f, offdist * archer_grapple_stiffness);
                        force *= Maths::Min(archer_grapple_force_limit, Maths::Max(0.0f, offdist + archer_grapple_slack) * archer_grapple_force);
                    }
                    else
                    {
                        force.Set(0, 0);
                    }
                }
    
                //left map? too long? close grapple
                if (archer.grapple_pos.x < 0 ||
                       archer.grapple_pos.x > (map.tilemapwidth)*map.tilesize ||
                       dist > archer_grapple_length * 3.0f)
                {
                    if (canSend(this))
                    {
                        archer.grappling = false;
                        SyncGrapple(this);
                    }
                }
                else if (archer.grapple_id == 0xffff) //not stuck
                {
                    const f32 drag = map.isInWater(archer.grapple_pos) ? 0.7f : 0.90f;
                    const Vec2f gravity(0, 1);
    
                    print("grapple not stuck");
                    archer.grapple_vel = (archer.grapple_vel * drag) + gravity - (force * (2 / this.getMass()));
    
                    Vec2f next = archer.grapple_pos + archer.grapple_vel;
                    next -= offset;
    
                    Vec2f dir = next - archer.grapple_pos;
                    f32 delta = dir.Normalize();
                    bool found = false;
                    const f32 step = map.tilesize * 0.5f;
                    while (delta > 0 && !found) //fake raycast
                    {
                        if (delta > step)
                        {
                            archer.grapple_pos += dir * step;
                        }
                        else
                        {
                            archer.grapple_pos = next;
                        }
                        delta -= step;
                        found = checkGrappleStep(this, archer, map, dist);
                    }
    
                }
                else //stuck -> pull towards pos
                {
                    print("grapple stuck");
                    //wallrun/jump reset to make getting over things easier
                    //at the top of grapple
                    if (this.isOnWall()) //on wall
                    {
                        //close to the grapple point
                        //not too far above
                        //and moving downwards
                        Vec2f dif = pos - archer.grapple_pos;
                        if (this.getVelocity().y > 0 &&
                               dif.y > -10.0f &&
                               dif.Length() < 24.0f)
                        {
                            //need move vars
                            RunnerMoveVars@ moveVars;
                            if (this.get("moveVars", @moveVars))
                            {
                                moveVars.walljumped_side = Walljump::NONE;
                                moveVars.wallrun_start = pos.y;
                                moveVars.wallrun_current = pos.y;
                            }
                        }
                    }
    
    
                    CBlob@ b = null;
                    if (archer.grapple_id != 0)
                    {
                        @b = getBlobByNetworkID(archer.grapple_id);
                        if (b is null)
                        {
                            archer.grapple_id = 0;
                        }
                    }
    
                    if (b !is null)
                    {
                        archer.grapple_pos = b.getPosition();
                        if (b.isKeyJustPressed(key_action1) ||
                               b.isKeyJustPressed(key_action3) ||
                               this.isKeyPressed(key_use))
                        {
                            if (canSend(this))
                            {
                                archer.grappling = false;
                                SyncGrapple(this);
                            }
                        }
                    }
                    else if (shouldReleaseGrapple(this, archer, map))
                    {
                        if (canSend(this))
                        {
                            archer.grappling = false;
                            SyncGrapple(this);
                        }
                    }
    
                    this.AddForce(force);
                    Vec2f target = (this.getPosition() + offset);
                    if (!map.rayCastSolid(this.getPosition(), target) &&
                        (this.getVelocity().Length() > 2 || !this.isOnMap()))
                    {
                        this.setPosition(target);
                    }
    
                    if (b !is null)
                        b.AddForce(-force * (b.getMass() / this.getMass()));
    
                }
            }
    
        }
    }
    
    void onCommand(CBlob@ this, u8 cmd, CBitStream @params)
    {
        if (cmd == this.getCommandID(grapple_sync_cmd))
        {
            HandleGrapple(this, params, !canSend(this));
            print("GRAPPLE COMMAND!");
        }
    }
    
    
    
    bool checkGrappleStep(CBlob@ this, ArcherInfo@ archer, CMap@ map, const f32 dist)
    {
        if (map.getSectorAtPosition(archer.grapple_pos, "barrier") !is null)  //red barrier
        {
            if (canSend(this))
            {
                archer.grappling = false;
                SyncGrapple(this);
            }
        }
        else if (grappleHitMap(archer, map, dist))
        {
            archer.grapple_id = 0;
    
            archer.grapple_ratio = Maths::Max(0.2, Maths::Min(archer.grapple_ratio, dist / archer_grapple_length));
    
            if (canSend(this)) SyncGrapple(this);
    
            return true;
        }
        else
        {
            CBlob@ b = map.getBlobAtPosition(archer.grapple_pos);
            if (b !is null)
            {
                if (b is this)
                {
                    //can't grapple self if not reeled in
                    if (archer.grapple_ratio > 0.5f)
                        return false;
    
                    if (canSend(this))
                    {
                        archer.grappling = false;
                        SyncGrapple(this);
                    }
    
                    return true;
                }
                else if (b.isCollidable() && b.getShape().isStatic() && !b.hasTag("ignore_arrow"))
                {
                    //TODO: Maybe figure out a way to grapple moving blobs
                    //        without massive desync + forces :)
    
                    archer.grapple_ratio = Maths::Max(0.2, Maths::Min(archer.grapple_ratio, b.getDistanceTo(this) / archer_grapple_length));
    
                    archer.grapple_id = b.getNetworkID();
                    if (canSend(this))
                    {
                        SyncGrapple(this);
                    }
    
                    return true;
                }
            }
        }
    
        return false;
    }
    
    bool grappleHitMap(ArcherInfo@ archer, CMap@ map, const f32 dist = 16.0f)
    {
        return  map.isTileSolid(archer.grapple_pos + Vec2f( 0, -3)) ||            //fake quad
               map.isTileSolid(archer.grapple_pos + Vec2f( 3,  0)) ||
               map.isTileSolid(archer.grapple_pos + Vec2f(-3,  0)) ||
               map.isTileSolid(archer.grapple_pos + Vec2f( 0,  3)) ||
               (dist > 10.0f && map.getSectorAtPosition(archer.grapple_pos, "tree") !is null);   //tree stick
    }
    
    bool shouldReleaseGrapple(CBlob@ this, ArcherInfo@ archer, CMap@ map)
    {
        return !grappleHitMap(archer, map) || this.isKeyPressed(key_use);
    }
    
    bool canSend(CBlob@ this)
    {
        return (this.isMyPlayer() || this.getPlayer() is null || this.getPlayer().isBot());
    }