📄 p_inter.c
字号:
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 + -