⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_inter.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 5 页
字号:
boolean P_ChickenMorph(mobj_t *actor){    mobj_t *fog;    mobj_t *chicken;    mobj_t *target;    mobjtype_t moType;    fixed_t x;    fixed_t y;    fixed_t z;    angle_t angle;    int ghost;        if(actor->player)    {        return(false);    }    moType = actor->type;    switch(moType)    {        case MT_POD:        case MT_CHICKEN:        case MT_HHEAD:        case MT_MINOTAUR:        case MT_SORCERER1:        case MT_SORCERER2:            return(false);        default:            break;    }    x = actor->x;    y = actor->y;    z = actor->z;    angle = actor->angle;    ghost = actor->flags&MF_SHADOW;    target = actor->target;    P_SetMobjState(actor, S_FREETARGMOBJ);    fog = P_SpawnMobj(x, y, z+TELEFOGHEIGHT, MT_TFOG);    S_StartSound(fog, sfx_telept);    chicken = P_SpawnMobj(x, y, z, MT_CHICKEN);    chicken->special2 = moType;    chicken->special1 = CHICKENTICS+P_Random();    chicken->flags |= ghost;    chicken->target = target;    chicken->angle = angle;    return(true);}//---------------------------------------------------------------------------//// FUNC P_AutoUseChaosDevice////---------------------------------------------------------------------------boolean P_AutoUseChaosDevice(player_t *player){    int i;        for(i = 0; i < player->inventorySlotNum; i++)    {        if(player->inventory[i].type == arti_teleport)        {            P_PlayerUseArtifact(player, arti_teleport);            player->health = player->mo->health = (player->health+1)/2;            return(true);        }    }    return(false);}//---------------------------------------------------------------------------//// PROC P_AutoUseHealth////---------------------------------------------------------------------------void P_AutoUseHealth(player_t *player, int saveHealth){    int i;    int count;    int normalCount;    int normalSlot;    int superCount;    int superSlot;        normalCount = superCount = 0;    for(i = 0; i < player->inventorySlotNum; i++)    {        if(player->inventory[i].type == arti_health)        {            normalSlot = i;            normalCount = player->inventory[i].count;        }        else if(player->inventory[i].type == arti_superhealth)        {            superSlot = i;            superCount = player->inventory[i].count;        }    }    if((gameskill == sk_baby) && (normalCount*25 >= saveHealth))    { // Use quartz flasks        count = (saveHealth+24)/25;        for(i = 0; i < count; i++)            P_PlayerUseArtifact( player, arti_health);    }    else if(superCount*100 >= saveHealth)    { // Use mystic urns        count = (saveHealth+99)/100;        for(i = 0; i < count; i++)            P_PlayerUseArtifact( player, arti_superhealth);    }    else if((gameskill == sk_baby)        && (superCount*100+normalCount*25 >= saveHealth))    { // Use mystic urns and quartz flasks        count = (saveHealth+24)/25;        for(i = 0; i < count; i++)            P_PlayerUseArtifact( player, arti_health);        saveHealth -= count*25;        count = (saveHealth+99)/100;        for(i = 0; i < count; i++)            P_PlayerUseArtifact( player, arti_superhealth);    }    player->mo->health = player->health;}//// P_DamageMobj// Damages both enemies and players// "inflictor" is the thing that caused the damage//  creature or missile, can be NULL (slime, etc)// "source" is the thing to target after taking damage//  creature or NULL// Source and inflictor are the same for melee attacks.// Source can be NULL for slime, barrel explosions// and other environmental stuff.//boolean P_DamageMobj ( mobj_t*   target,                       mobj_t*   inflictor,                       mobj_t*   source,                       int       damage ){    unsigned    ang;    int         saved;    player_t*   player;    fixed_t     thrust;    boolean     takedamage;  // false on some case in teamplay    if ( !(target->flags & MF_SHOOTABLE) )        return false; // shouldn't happen...    if (target->health <= 0)        return false;    if ( target->flags & MF_SKULLFLY )    {        // Minotaur is invulnerable during charge attack        if(target->type == MT_MINOTAUR)            return false;        target->momx = target->momy = target->momz = 0;    }    player = target->player;    if (player && gameskill == sk_baby)        damage >>= 1;   // take half damage in trainer mode    // Special damage types    if(inflictor)    {        switch(inflictor->type)        {        case MT_EGGFX:            if(player)            {                P_ChickenMorphPlayer(player);            }            else            {                P_ChickenMorph(target);            }            return false; // Always return        case MT_WHIRLWIND:            return P_TouchWhirlwind(target);        case MT_MINOTAUR:            if(inflictor->flags&MF_SKULLFLY)            { // Slam only when in charge mode                P_MinotaurSlam(inflictor, target);                return true;            }            break;        case MT_MACEFX4: // Death ball            if((target->flags2&MF2_BOSS) || target->type == MT_HHEAD)            { // Don't allow cheap boss kills                break;            }            else if(target->player)            { // Player specific checks                if(target->player->powers[pw_invulnerability])                { // Can't hurt invulnerable players                    break;                }                if(P_AutoUseChaosDevice(target->player))                { // Player was saved using chaos device                    return false;                }            }            damage = 10000; // Something's gonna die            break;        case MT_PHOENIXFX2: // Flame thrower            if(target->player && P_Random() < 128)            { // Freeze player for a bit                target->reactiontime += 4;            }            break;        case MT_RAINPLR1: // Rain missiles        case MT_RAINPLR2:        case MT_RAINPLR3:        case MT_RAINPLR4:            if(target->flags2&MF2_BOSS)            { // Decrease damage for bosses                damage = (P_Random()&7)+1;            }            break;        case MT_HORNRODFX2:        case MT_PHOENIXFX1:            if(target->type == MT_SORCERER2 && P_Random() < 96)            { // D'Sparil teleports away                P_DSparilTeleport(target);                return false;            }            break;        case MT_BLASTERFX1:        case MT_RIPPER:            if(target->type == MT_HHEAD)            { // Less damage to Ironlich bosses                damage = P_Random()&1;                if(!damage)                    return false;            }            break;        default:            break;        }    }    // Some close combat weapons should not    // inflict thrust and push the victim out of reach,    // thus kick away unless using the chainsaw.    if (inflictor        && !(target->flags & MF_NOCLIP)        && !(inflictor->flags2&MF2_NODMGTHRUST)        && (!source            || !source->player            || source->player->readyweapon != wp_chainsaw))    {        fixed_t            amomx, amomy, amomz=0;//SoM: 3/28/2000        extern consvar_t   cv_allowrocketjump;        ang = R_PointToAngle2 ( inflictor->x,                                inflictor->y,                                target->x,                                target->y);        if (gamemode == heretic )            thrust = damage*(FRACUNIT>>3)*150/target->info->mass;        else            thrust = damage*(FRACUNIT>>3)*100/target->info->mass;        // sometimes a target shot down might fall off a ledge forwards        if ( damage < 40             && damage > target->health             && target->z - inflictor->z > 64*FRACUNIT             && (P_Random ()&1) )        {            ang += ANG180;            thrust *= 4;        }        ang >>= ANGLETOFINESHIFT;        if(gamemode == heretic && source && source->player && (source == inflictor)            && source->player->powers[pw_weaponlevel2]            && source->player->readyweapon == wp_staff)        {            // Staff power level 2            target->momx += FixedMul(10*FRACUNIT, finecosine[ang]);            target->momy += FixedMul(10*FRACUNIT, finesine[ang]);            if(!(target->flags&MF_NOGRAVITY))            {                target->momz += 5*FRACUNIT;            }        }        else        {            amomx = FixedMul (thrust, finecosine[ang]);            amomy = FixedMul (thrust, finesine[ang]);            target->momx += amomx;            target->momy += amomy;                        // added momz (do it better for missiles explotion)            if (source && demoversion>=124 && (demoversion<129 || !cv_allowrocketjump.value))            {                int dist,z;                                if(source==target) // rocket in yourself (suicide)                {                    viewx=inflictor->x;                    viewy=inflictor->y;                    z=inflictor->z;                }                else                {                    viewx=source->x;                    viewy=source->y;                    z=source->z;                }                dist=R_PointToDist(target->x,target->y);                                viewx=0;                viewy=z;                ang = R_PointToAngle(dist,target->z);                                ang >>= ANGLETOFINESHIFT;                amomz = FixedMul (thrust, finesine[ang]);            }            else //SoM: 2/28/2000: Added new function.            if(demoversion >= 129 && cv_allowrocketjump.value)            {                fixed_t delta1 = abs(inflictor->z - target->z);                fixed_t delta2 = abs(inflictor->z - (target->z + target->height));                amomz = (abs(amomx) + abs(amomy))>>1;                                if(delta1 >= delta2 && inflictor->momz < 0)                    amomz = -amomz;            }            target->momz += amomz;#ifdef CLIENTPREDICTION2            if( target->player && target->player->spirit )            {                target->player->spirit->momx += amomx;                target->player->spirit->momy += amomy;                target->player->spirit->momz += amomz;            }#endif          }    }    takedamage = false;    // player specific    if (player && (target->flags & MF_CORPSE)==0)    {        // end of game hell hack        if (target->subsector->sector->special == 11            && damage >= target->health)        {            damage = target->health - 1;        }        // Below certain threshold,        // ignore damage in GOD mode, or with INVUL power.        if ( damage < 1000             && ( (player->cheats&CF_GODMODE)                  || player->powers[pw_invulnerability] ) )        {            return false;        }        if (player->armortype)        {            if (player->armortype == 1)                saved = gamemode == heretic ? damage>>1 : damage/3;            else                saved = gamemode == heretic ? (damage>>1)+(damage>>2) : damage/2;            if (player->armorpoints <= saved)            {                // armor is used up                saved = player->armorpoints;                player->armortype = 0;            }            player->armorpoints -= saved;            damage -= saved;        }        // added team play and teamdamage (view logboris at 13-8-98 to understand)        if( demoversion < 125   || // support old demoversion            cv_teamdamage.value ||            damage>1000         || // telefrag            source==target      ||            !source             ||            !source->player     ||            (             cv_deathmatch.value             &&             (!cv_teamplay.value ||              !ST_SameTeam(source->player,player)             )            )          )        {            if(damage >= player->health                && ((gameskill == sk_baby) || cv_deathmatch.value)                && !player->chickenTics)            { // Try to use some inventory health                P_AutoUseHealth(player, damage-player->health+1);            }            player->health -= damage;   // mirror mobj health here for Dave            if (player->health < 0)                player->health = 0;            takedamage = true;            player->damagecount += damage;  // add damage after armor / invuln            if (player->damagecount > 100)                player->damagecount = 100;  // teleport stomp does 10k points...            //added:22-02-98: force feedback ??? electro-shock???            if (player == &players[consoleplayer])                I_Tactile (40,10,40+min(damage, 100)*2);        }        player->attacker = source;    }    else        takedamage = true;    if( takedamage )    {        // do the damage        target->health -= damage;        if (target->health <= 0)        {            target->special1 = damage;            if(player && inflictor && !player->chickenTics)            { // Check for flame death                if((inflictor->flags2&MF2_FIREDAMAGE)                    || ((inflictor->type == MT_PHOENIXFX1)                    && (target->health > -50) && (damage > 25)))                {                    target->flags2 |= MF2_FIREDAMAGE;                }            }            P_KillMobj ( target, inflictor, source );            return true;        }        if ( (P_Random () < target->info->painchance)             && !(target->flags&(MF_SKULLFLY|MF_CORPSE)) )        {            target->flags |= MF_JUSTHIT;    // fight ba

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -