Example #1
0
double c_canberra_expected(long n, long k)
{
  double sum = 0.0;
  long t;
  
  for (t=1; t<=k; t++)
    sum += t * (a_harm(2 * k - t) - a_harm(t));
  
  return 2.0 / n * sum + (2.0 * (n - k) / n) * 
    (2 * (k + 1) * (harm(2 * k + 1) - harm(k + 1)) - k);
}
Example #2
0
void LVL_Npc::doHarm(int damageReason)
{
    int damageLevel=1;
    //call Lua
    //onHarm(killReason, out_DamageLevel)

    harm(damageLevel, damageReason);
}
Example #3
0
void LuaProxy::NPC::harm(short harmType, float damage, lua_State * L)
{
    if (!isValid_throw(L)) return;

    // Patch all instructions which add a damage amount to the NPC
    auto patchSet = PatchCollection(
        PATCH(0xA2A2D1 + 2).dword((DWORD)&damage),
        PATCH(0xA2A418 + 2).dword((DWORD)&damage),
        PATCH(0xA2A45C + 2).dword((DWORD)&damage),
        PATCH(0xA2A5C5 + 2).dword((DWORD)&damage),
        PATCH(0xA2A5CD + 2).dword((DWORD)&damage),
        PATCH(0xA2A62F + 2).dword((DWORD)&damage),
        PATCH(0xA2A745 + 2).dword((DWORD)&damage),
        PATCH(0xA2A766 + 2).dword((DWORD)&damage),
        PATCH(0xA2A7AB + 2).dword((DWORD)&damage),
        PATCH(0xA2A94E + 2).dword((DWORD)&damage),
        PATCH(0xA2A9FC + 2).dword((DWORD)&damage),
        PATCH(0xA2AA3C + 2).dword((DWORD)&damage),
        PATCH(0xA2AB08 + 2).dword((DWORD)&damage),
        PATCH(0xA2AB63 + 2).dword((DWORD)&damage),
        PATCH(0xA2AD8E + 2).dword((DWORD)&damage),
        PATCH(0xA2C124 + 2).dword((DWORD)&damage),
        PATCH(0xA2C164 + 2).dword((DWORD)&damage),
        PATCH(0xA2C5B9 + 2).dword((DWORD)&damage),
        PATCH(0xA2C672 + 2).dword((DWORD)&damage),
        PATCH(0xA2C6CC + 2).dword((DWORD)&damage),
        PATCH(0xA2C7B7 + 2).dword((DWORD)&damage),
        PATCH(0xA2C826 + 2).dword((DWORD)&damage),
        PATCH(0xA2E1B1 + 2).dword((DWORD)&damage),
        PATCH(0xA2E20E + 2).dword((DWORD)&damage),
        PATCH(0xA2E280 + 2).dword((DWORD)&damage),
        PATCH(0xA2FE7F + 2).dword((DWORD)&damage),
        PATCH(0xA2FEC7 + 2).dword((DWORD)&damage),
        PATCH(0xA2FF01 + 2).dword((DWORD)&damage),
        PATCH(0xA2FFA7 + 2).dword((DWORD)&damage),
        PATCH(0xA300B2 + 2).dword((DWORD)&damage),
        PATCH(0xA300FA + 2).dword((DWORD)&damage),
        PATCH(0xA30134 + 2).dword((DWORD)&damage)
        );

    patchSet.Apply();
    harm(harmType, L);
    patchSet.Unapply();
}
Example #4
0
void LuaProxy::NPC::harm(lua_State * L)
{
    harm(HARM_TYPE_NPC, L);
}
Example #5
0
double o_harm(long n)
{
  return harm(n) - 0.5 * harm(floor((double) n / 2.0));
}
Example #6
0
double e_harm(long n)
{
  return 0.5 * harm(floor((double) n / 2.0));
}
void LVL_Player::solveCollision(PGE_Phys_Object *collided)
{
    if(!collided) return;

    switch(collided->type)
    {
        case PGE_Phys_Object::LVLBlock:
        {
            LVL_Block *blk= static_cast<LVL_Block*>(collided);
            if(blk)
            {
                if(blk->destroyed)
                {
                    #ifdef COLLIDE_DEBUG
                    qDebug() << "Destroyed!";
                    #endif
                    break;
                }
            }
            else
            {
                #ifdef COLLIDE_DEBUG
                qDebug() << "Wrong cast";
                #endif
                break;
            }

            if( ((!forceCollideCenter)&&(!collided->posRect.collideRect(posRect)))||
                ((forceCollideCenter)&&(!collided->posRect.collideRectDeep(posRect, 1.0, -3.0))) )
            {
                #ifdef COLLIDE_DEBUG
                qDebug() << "No, is not collidng";
                #endif
                break;
            }
            #ifdef COLLIDE_DEBUG
            qDebug() << "Collided item! "<<collided->type<<" " <<collided->posRect.center().x()<<collided->posRect.center().y();
            #endif

            if((bumpUp||bumpDown)&&(!forceCollideCenter))
            {
                #ifdef COLLIDE_DEBUG
                qDebug() << "Bump? U'r dumb!";
                #endif
                break;
            }

//            PGE_PointF c1 = posRect.center();
//            PGE_RectF &r1 = posRect;
//            PGE_PointF cc = collided->posRect.center();
//            PGE_RectF  rc = collided->posRect;

            switch(collided->collide_player)
            {
                case COLLISION_TOP:
                {
                    if(isCollideFloorToponly(collided))
                    {
                        if(blk->isHidden) break;
                        collided_bottom[(intptr_t)collided]=collided;//bottom of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==2||blk->setup->danger==-3||blk->setup->danger==4) harm(1);
                        #ifdef COLLIDE_DEBUG
                        qDebug() << "Top of block";
                        #endif
                    }
                }
                break;
                case COLLISION_ANY:
                {
                    #ifdef COLLIDE_DEBUG
                    bool found=false;
                    #endif
                    //*****************************Feet of player****************************/
                    if(
                        (( (blk->shape==LVL_Block::shape_rect)||
                           (blk->shape==LVL_Block::shape_tr_bottom_left)||
                           (blk->shape==LVL_Block::shape_tr_bottom_right) ) && isCollideFloor(collided))||
                        ((blk->shape==LVL_Block::shape_tr_top_right)&&isCollideSlopeFloor(collided, SLOPE_RIGHT)) ||
                        ((blk->shape==LVL_Block::shape_tr_top_left)&&isCollideSlopeFloor(collided, SLOPE_LEFT))

                      ){
                        if(blk->isHidden) break;
                        collided_bottom[(intptr_t)collided]=collided;//bottom of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==2||blk->setup->danger==-3||blk->setup->danger==4) harm(1);
                    }
                    //*****************************Head of player****************************/
                    else if(
                            (( (blk->shape==LVL_Block::shape_rect)||
                                (blk->shape==LVL_Block::shape_tr_top_left)||
                                (blk->shape==LVL_Block::shape_tr_top_right)) &&
                                isCollideCelling(collided, _heightDelta, forceCollideCenter))||
                            ((blk->shape==LVL_Block::shape_tr_bottom_right)&&isCollideSlopeCelling(collided, SLOPE_RIGHT)) ||
                            ((blk->shape==LVL_Block::shape_tr_bottom_left)&&isCollideSlopeCelling(collided, SLOPE_LEFT))
                           )
                    {
                        collided_top[(intptr_t)collided]=collided;//top of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==-2||blk->setup->danger==-3||blk->setup->danger==4) harm(1);
                    }
                    //*****************************Left****************************/
                    else if( (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_rect))||
                             (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_tr_top_left)
                              &&(posRect.bottom()>=(collided->posRect.top()+SL_HeightTopRight(collided)+1.0)))||
                             (isCollideLeft(collided)&&(blk->shape==LVL_Block::shape_tr_bottom_left)
                              &&(posRect.top()<=(collided->posRect.bottom()-SL_HeightTopRight(collided)-1.0))) )
                    {
                        if(blk->isHidden) break;
                        collided_left[(intptr_t)collided]=collided;//right of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==-1||blk->setup->danger==3||blk->setup->danger==4) harm(1);
                    }
                    //*****************************Right****************************/
                    else if( (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_rect))||
                             (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_tr_top_right)
                             &&(posRect.bottom()>=(collided->posRect.top()+SL_HeightTopLeft(collided)+1.0)))||
                             (isCollideRight(collided)&&(blk->shape==LVL_Block::shape_tr_bottom_right)
                             &&(posRect.top()<=(collided->posRect.bottom()-SL_HeightTopLeft(collided)-1.0)))
                           )
                    {
                        if(blk->isHidden) break;
                        collided_right[(intptr_t)collided]=collided;//left of player
                        if(blk->setup->lava) kill(DEAD_burn);
                        else if(blk->setup->danger==1||blk->setup->danger==3||blk->setup->danger==4) harm(1);
                    }


                    float c=forceCollideCenter? 0.0f : 1.0f;
                    //*****************************Center****************************/
                    if( ((!forceCollideCenter && blk->shape==LVL_Block::shape_rect)||(forceCollideCenter))
                            && blk->posRect.collideRectDeep(posRect,
                                                     fabs(_velocityX_prev+_velocityX_add)*c+c*2.0,
                                                     fabs(_velocityY_prev+_velocityY_add)*c+c*2.0)
                            )
                    {
                        if(blk->isHidden && !forceCollideCenter) break;
                        collided_center[(intptr_t)collided]=collided;
                    }
                    break;
                }
            default: break;
            }
            break;
        }
        case PGE_Phys_Object::LVLWarp:
        {
            contactedWarp = static_cast<LVL_Warp*>(collided);
            if(contactedWarp)
                contactedWithWarp=true;
            break;
        }
        case PGE_Phys_Object::LVLBGO:
        {
            LVL_Bgo *bgo= static_cast<LVL_Bgo*>(collided);
            if(bgo)
            {
                if(bgo->setup->climbing)
                {
                    bool set=climbable_map.isEmpty();
                    climbable_map[(intptr_t)collided]=collided;
                    if(set)
                        climbableHeight=collided->posRect.top();
                    else if(collided->top()<climbableHeight)
                        climbableHeight=collided->top();
                }
            }
            break;
        }
        case PGE_Phys_Object::LVLNPC:
        {
            LVL_Npc *npc= static_cast<LVL_Npc*>(collided);
            if(npc)
            {
                if(npc->isKilled())        break;

                if(!npc->data.msg.isEmpty())
                {
                    collided_talkable_npc=npc;
                }
                if(npc->data.friendly) break;
                if(npc->isGenerator) break;
                if(npc->setup->climbable)
                {
                    bool set=climbable_map.isEmpty();
                    climbable_map[(intptr_t)collided]=collided;
                    if(set)
                        climbableHeight=collided->posRect.top();
                    else if(collided->top()<climbableHeight)
                        climbableHeight=collided->top();
                }

                if((!npc->data.friendly)&&(npc->setup->takable))
                {
                    collided_talkable_npc=NULL;
                    npc->doHarm(LVL_Npc::DAMAGE_TAKEN);
                    kill_npc(npc, LVL_Player::NPC_Taked_Coin);
                }


                if( ((!forceCollideCenter)&&(!collided->posRect.collideRect(posRect)))||
                    ((forceCollideCenter)&&(!collided->posRect.collideRectDeep(posRect, 1.0, -3.0))) )
                {
                    break;
                }

                if((bumpUp||bumpDown)&&(!forceCollideCenter))
                    break;

                if(!npc->isActivated) break;

                //PGE_PointF c1 = posRect.center();
                //PGE_RectF &r1 = posRect;
                //PGE_PointF cc = collided->posRect.center();
                //PGE_RectF  rc = collided->posRect;

                switch(collided->collide_player)
                {
                    case COLLISION_TOP:
                    {
                        if(isCollideFloorToponly(collided))
                        {
                            collided_bottom[(intptr_t)collided]=collided;//bottom of player
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Top of block";
                            #endif
                        } else {
                            if( npc->posRect.collideRect(posRect))
                            {
                               if(npc->setup->hurt_player & !npc->setup->kill_on_jump) harm(1);
                            }
                        }

                    }
                    break;
                    case COLLISION_ANY:
                    {
                        #ifdef COLLIDE_DEBUG
                        bool found=false;
                        #endif
                        //double xSpeed = Maths::max(fabs(speedX()+_velocityX_add), fabs(_velocityX_prev+_velocityX_add)) * Maths::sgn(speedX()+_velocityX_add);
                        //double ySpeed = Maths::max(fabs(speedY()+_velocityY_add), fabs(_velocityY_prev+_velocityY_add)) * Maths::sgn(speedY()+_velocityY_add);
                        //*****************************Feet of player****************************/
                        if(isCollideFloor(collided))
                        {
                                collided_bottom[(intptr_t)collided]=collided;//bottom of player
                                #ifdef COLLIDE_DEBUG
                                qDebug() << "Top of block";
                                found=true;
                                #endif
                        }
                        //*****************************Head of player****************************/
                        else if( isCollideCelling(collided, _heightDelta, forceCollideCenter) )
                        {
                            collided_top[(intptr_t)collided]=collided;//top of player
                            if(npc->setup->hurt_player) harm(1);
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Bottom of block";
                            found=true;
                            #endif
                        }
                        //*****************************Left****************************/
                        else if( isCollideLeft(collided) )
                        {
                            collided_left[(intptr_t)collided]=collided;//right of player
                            if(npc->setup->hurt_player) harm(1);
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Right of block";
                            #endif
                        }
                        //*****************************Right****************************/
                        else if( isCollideRight(collided) )
                        {
                            collided_right[(intptr_t)collided]=collided;//left of player
                            if(npc->setup->hurt_player) harm(1);
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Left of block";
                            found=true;
                            #endif
                        }


                        float c=forceCollideCenter? 0.0f : 1.0f;
                        //*****************************Center****************************/
                        #ifdef COLLIDE_DEBUG
                        qDebug() << "block" <<posRect.top()<<":"<<blk->posRect.bottom()
                                 << "block" <<posRect.bottom()<<":"<<blk->posRect.top()<<" collide?"<<
                                    blk->posRect.collideRectDeep(posRect,
                                                                                         fabs(_velocityX_prev)*c+c*2.0,
                                                                                         fabs(_velocityY_prev)*c+c*2.0) <<
                                    "depths: "<< fabs(_velocityX_prev)*c+c*2.0 <<
                                fabs(_velocityY_prev)*c+c;
                        #endif
                        if( npc->posRect.collideRectDeep(posRect,
                                                         fabs(_velocityX_prev)*c+c*2.0,
                                                         fabs(_velocityY_prev)*c+c*2.0)
                                )
                        {
                            if(npc->setup->hurt_player) harm(1);
                            if(!forceCollideCenter) break;
                            collided_center[(intptr_t)collided]=collided;
                            #ifdef COLLIDE_DEBUG
                            qDebug() << "Center of block";
                            found=true;
                            #endif
                        }

                        #ifdef COLLIDE_DEBUG
                        qDebug() << "---checked---" << (found?"and found!": "but nothing..." )<<
                                    r1.left()<< "<="<< rc.right()<<"+"<<xSpeed ;
                        #endif
                        break;
                    }
                case COLLISION_NONE:
                    { //Detect top of stompable NPC!
                        if(!npc->setup->kill_on_jump)
                        {
                            if( npc->posRect.collideRect(posRect))
                            {
                               if(npc->setup->hurt_player) harm(1);
                            }
                            break;
                        }

//                        PGE_RectF &r1=posRect;
//                        PGE_RectF  rc = collided->posRect;
//                        float summSpeedY=(speedY()+_velocityY_add)-(collided->speedY()+collided->_velocityY_add);
//                        float summSpeedYprv=_velocityY_prev-collided->_velocityY_prev;
                        if(isCollideFloorToponly(collided))
//                                (
//                                    (summSpeedY >= 0.0)
//                                    &&
//                                    (r1.bottom() < rc.top()+summSpeedYprv)
//                                    &&
//                                    (
//                                         (r1.left()<rc.right()-1 ) &&
//                                         (r1.right()>rc.left()+1 )
//                                     )
//                                 )
//                                ||
//                                (r1.bottom() <= rc.top())
//                                )
                        {
                            npc->doHarm(LVL_Npc::DAMAGE_STOMPED);
                            this->bump(true);
                            //Reset floating state
                            floating_timer = floating_maxtime;
                            if(floating_isworks)
                            {
                                floating_isworks=false;
                                setGravityScale(climbing?0:physics_cur.gravity_scale);
                            }
                            kill_npc(npc, NPC_Stomped);
                        } else {
                            if( npc->posRect.collideRect(posRect))
                            {
                                //The second half of this "if" statement is there to fix a bug with falling collisions,
                                //and should NOT remain here because it is not how we should handle this!
                                //The bug occurs when the player is moving fast enough when they land on an enemy that they
                                //partially enter the enemy before the collision is resolved, causing the engine to think
                                //that the player is INSIDE the NPC, when they are actually only JUMPING on the NPC.
                                if(npc->setup->hurt_player & (!npc->setup->kill_on_jump || colliding_ySpeed > -1.0f)) harm(1);
                            }
                        }
                        break;
                    }//case COLLISION_NONE
                default: break;
                }
            }
            break;
        }
        case PGE_Phys_Object::LVLPhysEnv:
        {
            LVL_PhysEnv *env= static_cast<LVL_PhysEnv*>(collided);
            if(env)
            {
                if(env) environments_map[(intptr_t)env]=env->env_type;
            }
            break;
        }
    default: break;
    }
}