📄 p_user.c
字号:
mo->flags2 &= ~MF2_SLIDE; }}void P_BlastMobj(mobj_t *source, mobj_t *victim, fixed_t strength){ angle_t angle,ang; mobj_t *mo; fixed_t x,y,z; angle = R_PointToAngle2(source->x, source->y, victim->x, victim->y); angle >>= ANGLETOFINESHIFT; if (strength < BLAST_FULLSTRENGTH) { victim->momx = FixedMul(strength, finecosine[angle]); victim->momy = FixedMul(strength, finesine[angle]); if (victim->player) { // Players handled automatically } else { victim->flags2 |= MF2_SLIDE; victim->flags2 |= MF2_BLASTED; } } else // full strength blast from artifact { if (victim->flags&MF_MISSILE) { switch(victim->type) { case MT_SORCBALL1: // don't blast sorcerer balls case MT_SORCBALL2: case MT_SORCBALL3: return; break; case MT_MSTAFF_FX2: // Reflect to originator victim->special1 = (int)victim->target; victim->target = source; break; default: break; } } if (victim->type == MT_HOLY_FX) { if ((mobj_t *)(victim->special1) == source) { victim->special1 = (int)victim->target; victim->target = source; } } victim->momx = FixedMul(BLAST_SPEED, finecosine[angle]); victim->momy = FixedMul(BLAST_SPEED, finesine[angle]); // Spawn blast puff ang = R_PointToAngle2(victim->x, victim->y, source->x, source->y); ang >>= ANGLETOFINESHIFT; x = victim->x + FixedMul(victim->radius+FRACUNIT, finecosine[ang]); y = victim->y + FixedMul(victim->radius+FRACUNIT, finesine[ang]); z = victim->z - victim->floorclip + (victim->height>>1); mo=P_SpawnMobj(x, y, z, MT_BLASTEFFECT); if (mo) { mo->momx = victim->momx; mo->momy = victim->momy; } if (victim->flags&MF_MISSILE) { victim->momz = 8*FRACUNIT; mo->momz = victim->momz; } else { victim->momz = (1000/victim->info->mass)<<FRACBITS; } if (victim->player) { // Players handled automatically } else { victim->flags2 |= MF2_SLIDE; victim->flags2 |= MF2_BLASTED; } }}// Blast all mobj things awayvoid P_BlastRadius(player_t *player){ mobj_t *mo; mobj_t *pmo=player->mo; thinker_t *think; fixed_t dist; S_StartSound(pmo, SFX_ARTIFACT_BLAST); P_NoiseAlert(player->mo, player->mo); for(think = thinkercap.next; think != &thinkercap; think = think->next) { if(think->function != P_MobjThinker) { // Not a mobj thinker continue; } mo = (mobj_t *)think; if((mo == pmo) || (mo->flags2&MF2_BOSS)) { // Not a valid monster continue; } if ((mo->type == MT_POISONCLOUD) || // poison cloud (mo->type == MT_HOLY_FX) || // holy fx (mo->flags&MF_ICECORPSE)) // frozen corpse { // Let these special cases go } else if ((mo->flags&MF_COUNTKILL) && (mo->health <= 0)) { continue; } else if (!(mo->flags&MF_COUNTKILL) && !(mo->player) && !(mo->flags&MF_MISSILE)) { // Must be monster, player, or missile continue; } if (mo->flags2&MF2_DORMANT) { continue; // no dormant creatures } if ((mo->type == MT_WRAITHB) && (mo->flags2&MF2_DONTDRAW)) { continue; // no underground wraiths } if ((mo->type == MT_SPLASHBASE) || (mo->type == MT_SPLASH)) { continue; } if(mo->type == MT_SERPENT || mo->type == MT_SERPENTLEADER) { continue; } dist = P_AproxDistance(pmo->x - mo->x, pmo->y - mo->y); if(dist > BLAST_RADIUS_DIST) { // Out of range continue; } P_BlastMobj(pmo, mo, BLAST_FULLSTRENGTH); }}#define HEAL_RADIUS_DIST 255*FRACUNIT// Do class specific effect for everyone in radiusboolean P_HealRadius(player_t *player){ mobj_t *mo; mobj_t *pmo=player->mo; thinker_t *think; fixed_t dist; int effective=false; int amount; for(think = thinkercap.next; think != &thinkercap; think = think->next) { if(think->function != P_MobjThinker) { // Not a mobj thinker continue; } mo = (mobj_t *)think; if (!mo->player) continue; if (mo->health <= 0) continue; dist = P_AproxDistance(pmo->x - mo->x, pmo->y - mo->y); if(dist > HEAL_RADIUS_DIST) { // Out of range continue; } switch(player->class) { case PCLASS_FIGHTER: // Radius armor boost if ((P_GiveArmor(mo->player, ARMOR_ARMOR, 1)) || (P_GiveArmor(mo->player, ARMOR_SHIELD, 1)) || (P_GiveArmor(mo->player, ARMOR_HELMET, 1)) || (P_GiveArmor(mo->player, ARMOR_AMULET, 1))) { effective=true; S_StartSound(mo, SFX_MYSTICINCANT); } break; case PCLASS_CLERIC: // Radius heal amount = 50 + (P_Random()%50); if (P_GiveBody(mo->player, amount)) { effective=true; S_StartSound(mo, SFX_MYSTICINCANT); } break; case PCLASS_MAGE: // Radius mana boost amount = 50 + (P_Random()%50); if ((P_GiveMana(mo->player, MANA_1, amount)) || (P_GiveMana(mo->player, MANA_2, amount))) { effective=true; S_StartSound(mo, SFX_MYSTICINCANT); } break; case PCLASS_PIG: default: break; } } return(effective);}//----------------------------------------------------------------------------//// PROC P_PlayerNextArtifact////----------------------------------------------------------------------------void P_PlayerNextArtifact(player_t *player){ extern int inv_ptr; extern int curpos; if(player == &players[consoleplayer]) { inv_ptr--; if(inv_ptr < 6) { curpos--; if(curpos < 0) { curpos = 0; } } if(inv_ptr < 0) { inv_ptr = player->inventorySlotNum-1; if(inv_ptr < 6) { curpos = inv_ptr; } else { curpos = 6; } } player->readyArtifact = player->inventory[inv_ptr].type; }}//----------------------------------------------------------------------------//// PROC P_PlayerRemoveArtifact////----------------------------------------------------------------------------void P_PlayerRemoveArtifact(player_t *player, int slot){ int i; extern int inv_ptr; extern int curpos; player->artifactCount--; if(!(--player->inventory[slot].count)) { // Used last of a type - compact the artifact list player->readyArtifact = arti_none; player->inventory[slot].type = arti_none; for(i = slot+1; i < player->inventorySlotNum; i++) { player->inventory[i-1] = player->inventory[i]; } player->inventorySlotNum--; if(player == &players[consoleplayer]) { // Set position markers and get next readyArtifact inv_ptr--; if(inv_ptr < 6) { curpos--; if(curpos < 0) { curpos = 0; } } if(inv_ptr >= player->inventorySlotNum) { inv_ptr = player->inventorySlotNum-1; } if(inv_ptr < 0) { inv_ptr = 0; } player->readyArtifact = player->inventory[inv_ptr].type; } }}//----------------------------------------------------------------------------//// PROC P_PlayerUseArtifact////----------------------------------------------------------------------------void P_PlayerUseArtifact(player_t *player, artitype_t arti){ int i; for(i = 0; i < player->inventorySlotNum; i++) { if(player->inventory[i].type == arti) { // Found match - try to use if(P_UseArtifact(player, arti)) { // Artifact was used - remove it from inventory P_PlayerRemoveArtifact(player, i); if(player == &players[consoleplayer]) { if(arti < arti_firstpuzzitem) { S_StartSound(NULL, SFX_ARTIFACT_USE); } else { S_StartSound(NULL, SFX_PUZZLE_SUCCESS); } ArtifactFlash = 4; } } else if(arti < arti_firstpuzzitem) { // Unable to use artifact, advance pointer P_PlayerNextArtifact(player); } break; } }}//==========================================================================//// P_UseArtifact//// Returns true if the artifact was used.////==========================================================================boolean P_UseArtifact(player_t *player, artitype_t arti){ mobj_t *mo; angle_t angle; int i; int count; switch(arti) { case arti_invulnerability: if(!P_GivePower(player, pw_invulnerability)) { return(false); } break; case arti_health: if(!P_GiveBody(player, 25)) { return(false); } break; case arti_superhealth: if(!P_GiveBody(player, 100)) { return(false); } break; case arti_healingradius: if (!P_HealRadius(player)) { return(false); } break; case arti_torch: if(!P_GivePower(player, pw_infrared)) { return(false); } break; case arti_egg: mo = player->mo; P_SpawnPlayerMissile(mo, MT_EGGFX); P_SPMAngle(mo, MT_EGGFX, mo->angle-(ANG45/6)); P_SPMAngle(mo, MT_EGGFX, mo->angle+(ANG45/6)); P_SPMAngle(mo, MT_EGGFX, mo->angle-(ANG45/3)); P_SPMAngle(mo, MT_EGGFX, mo->angle+(ANG45/3)); break; case arti_fly: if(!P_GivePower(player, pw_flight)) { return(false); } if(player->mo->momz <= -35*FRACUNIT) { // stop falling scream S_StopSound(player->mo); } break; case arti_summon: mo = P_SpawnPlayerMissile(player->mo, MT_SUMMON_FX); if (mo) { mo->target = player->mo; mo->special1 = (int)(player->mo); mo->momz = 5*FRACUNIT; } break; case arti_teleport: P_ArtiTele(player); break; case arti_teleportother: P_ArtiTeleportOther(player); break; case arti_poisonbag: angle = player->mo->angle>>ANGLETOFINESHIFT; if(player->class == PCLASS_CLERIC) { mo = P_SpawnMobj(player->mo->x+16*finecosine[angle], player->mo->y+24*finesine[angle], player->mo->z- player->mo->floorclip+8*FRACUNIT, MT_POISONBAG); if(mo) { mo->target = player->mo; } } else if(player->class == PCLASS_MAGE) { mo = P_SpawnMobj(player->mo->x+16*finecosine[angle], player->mo->y+24*finesine[angle], player->mo->z- player->mo->floorclip+8*FRACUNIT, MT_FIREBOMB); if(mo) { mo->target = player->mo; } } else // PCLASS_FIGHTER, obviously (also pig, not so obviously) { mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z-player->mo->floorclip+35*FRACUNIT, MT_THROWINGBOMB); if(mo) { mo->angle = player->mo->angle+(((P_Random()&7)-4)<<24); mo->momz = 4*FRACUNIT+((player->lookdir)<<(FRACBITS-4)); mo->z += player->lookdir<<(FRACBITS-4); P_ThrustMobj(mo, mo->angle, mo->info->speed); mo->momx += player->mo->momx>>1; mo->momy += player->mo->momy>>1; mo->target = player->mo; mo->tics -= P_Random()&3; P_CheckMissileSpawn(mo); } } break; case arti_speed: if(!P_GivePower(player, pw_speed)) { return(false); } break; case arti_boostmana: if(!P_GiveMana(player, MANA_1, MAX_MANA)) { if(!P_GiveMana(player, MANA_2, MAX_MANA)) { return false; } } else { P_GiveMana(player, MANA_2, MAX_MANA); } break; case arti_boostarmor: count = 0; for(i = 0; i < NUMARMOR; i++) { count += P_GiveArmor(player, i, 1); // 1 point per armor type } if(!count) { return false; } break; case arti_blastradius: P_BlastRadius(player); break; case arti_puzzskull: case arti_puzzgembig: case arti_puzzgemred: case arti_puzzgemgreen1: case arti_puzzgemgreen2: case arti_puzzgemblue1: case arti_puzzgemblue2: case arti_puzzbook1: case arti_puzzbook2: case arti_puzzskull2: case arti_puzzfweapon: case arti_puzzcweapon: case arti_puzzmweapon: case arti_puzzgear1: case arti_puzzgear2: case arti_puzzgear3: case arti_puzzgear4: if(P_UsePuzzleItem(player, arti-arti_firstpuzzitem)) { return true; } else { P_SetYellowMessage(player, TXT_USEPUZZLEFAILED, false); return false; } break; default: return false; } return true;}//============================================================================//// A_SpeedFade////============================================================================void A_SpeedFade(mobj_t *actor){ actor->flags |= MF_SHADOW; actor->flags &= ~MF_ALTSHADOW; actor->sprite = actor->target->sprite;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -