DEFINE_ACTION_FUNCTION(AInventory, A_Raise) { PARAM_ACTION_PROLOGUE; if (self == nullptr) { return 0; } player_t *player = self->player; DPSprite *psp; if (nullptr == player) { return 0; } if (player->PendingWeapon != WP_NOCHANGE) { P_DropWeapon(player); return 0; } if (player->ReadyWeapon == nullptr) { return 0; } psp = player->GetPSprite(PSP_WEAPON); psp->y -= RAISESPEED; if (psp->y > WEAPONTOP) { // Not raised all the way yet return 0; } psp->y = WEAPONTOP; psp->SetState(player->ReadyWeapon->GetReadyState()); return 0; }
void AWeapon::EndPowerup () { if (SisterWeapon != NULL && WeaponFlags&WIF_POWERED_UP) { if (GetReadyState() != SisterWeapon->GetReadyState()) { if (Owner->player->PendingWeapon == NULL || Owner->player->PendingWeapon == WP_NOCHANGE) Owner->player->PendingWeapon = SisterWeapon; } else { DPSprite *psp = Owner->player->FindPSprite(PSP_WEAPON); if (psp != nullptr && psp->GetCaller() == Owner->player->ReadyWeapon) { // If the weapon changes but the state does not, we have to manually change the PSprite's caller here. psp->SetCaller(SisterWeapon); Owner->player->ReadyWeapon = SisterWeapon; } else { // Something went wrong. Initiate a regular weapon change. Owner->player->PendingWeapon = SisterWeapon; } } } }
void player_t::DestroyPSprites() { DPSprite *pspr = psprites; psprites = nullptr; while (pspr) { DPSprite *next = pspr->Next; pspr->Next = nullptr; pspr->Destroy(); pspr = next; } }
bool gl_IsHUDModelForPlayerAvailable (player_t * player) { if (player == nullptr || player->ReadyWeapon == nullptr) return false; DPSprite *psp = player->FindPSprite(PSP_WEAPON); if (psp == nullptr || psp->GetState() == nullptr) return false; FState* state = psp->GetState(); FSpriteModelFrame *smf = gl_FindModelFrame(player->ReadyWeapon->GetClass(), state->sprite, state->GetFrame(), false); return ( smf != nullptr ); }
void AWeapon::PostMorphWeapon () { DPSprite *pspr; if (Owner == nullptr) { return; } Owner->player->PendingWeapon = WP_NOCHANGE; Owner->player->ReadyWeapon = this; Owner->player->refire = 0; pspr = Owner->player->GetPSprite(PSP_WEAPON); pspr->y = WEAPONBOTTOM; pspr->SetState(GetUpState()); }
DEFINE_ACTION_FUNCTION(AActor, A_SelectSigilAttack) { PARAM_ACTION_PROLOGUE; DPSprite *pspr; int pieces; if (self->player == nullptr) { return 0; } pieces = static_cast<ASigil*>(self->player->ReadyWeapon)->NumPieces; pspr = self->player->GetPSprite(PSP_WEAPON); pspr->SetState(pspr->GetState() + 4*pieces - 3); return 0; }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Overlay) { PARAM_ACTION_PROLOGUE; PARAM_INT (layer); PARAM_STATE_OPT (state) { state = nullptr; } PARAM_BOOL_OPT (dontoverride) { dontoverride = false; } player_t *player = self->player; if (player == nullptr || (dontoverride && (player->FindPSprite(layer) != nullptr))) { ACTION_RETURN_BOOL(false); } DPSprite *pspr; pspr = new DPSprite(player, stateowner, layer); pspr->SetState(state); ACTION_RETURN_BOOL(true); }
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ClearOverlays) { PARAM_ACTION_PROLOGUE; PARAM_INT_OPT(start) { start = 0; } PARAM_INT_OPT(stop) { stop = 0; } PARAM_BOOL_OPT(safety) { safety = true; } if (self->player == nullptr) ACTION_RETURN_INT(0); if (!start && !stop) { start = INT_MIN; stop = safety ? PSP_TARGETCENTER - 1 : INT_MAX; } unsigned int count = 0; int id; for (DPSprite *pspr = self->player->psprites; pspr != nullptr; pspr = pspr->GetNext()) { id = pspr->GetID(); if (id < start || id == 0) continue; else if (id > stop) break; if (safety) { if (id >= PSP_TARGETCENTER) break; else if (id == PSP_STRIFEHANDS || id == PSP_WEAPON || id == PSP_FLASH) continue; } pspr->SetState(nullptr); count++; } ACTION_RETURN_INT(count); }
void DPSprite::NewTick() { // This function should be called after the beginning of a tick, before any possible // prprite-event, or near the end, after any possible psprite event. // Because data is reset for every tick (which it must be) this has no impact on savegames. for (int i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) { DPSprite *pspr = players[i].psprites; while (pspr) { pspr->processPending = true; pspr->ResetInterpolation(); pspr = pspr->Next; } } } }
DEFINE_ACTION_FUNCTION(AInventory, A_Lower) { PARAM_ACTION_PROLOGUE; player_t *player = self->player; DPSprite *psp; if (nullptr == player) { return 0; } if (nullptr == player->ReadyWeapon) { P_BringUpWeapon(player); return 0; } psp = player->GetPSprite(PSP_WEAPON); if (player->morphTics || player->cheats & CF_INSTANTWEAPSWITCH) { psp->y = WEAPONBOTTOM; } else { psp->y += LOWERSPEED; } if (psp->y < WEAPONBOTTOM) { // Not lowered all the way yet return 0; } if (player->playerstate == PST_DEAD) { // Player is dead, so don't bring up a pending weapon // Player is dead, so keep the weapon off screen P_SetPsprite(player, PSP_FLASH, nullptr); psp->SetState(player->ReadyWeapon->FindState(NAME_DeadLowered)); return 0; } // [RH] Clear the flash state. Only needed for Strife. P_SetPsprite(player, PSP_FLASH, nullptr); P_BringUpWeapon (player); return 0; }
void FGLRenderer::DrawTargeterSprites() { AActor * playermo=players[consoleplayer].camera; player_t * player=playermo->player; if(!player || playermo->renderflags&RF_INVISIBLE || !r_drawplayersprites || mViewActor!=playermo) return; gl_RenderState.EnableBrightmap(false); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold); gl_RenderState.BlendEquation(GL_FUNC_ADD); gl_RenderState.ResetColor(); gl_RenderState.SetTextureMode(TM_MODULATE); // The Targeter's sprites are always drawn normally. for (DPSprite *psp = player->FindPSprite(PSP_TARGETCENTER); psp != nullptr; psp = psp->GetNext()) { if (psp->GetState() != nullptr) DrawPSprite(player, psp, psp->x, psp->y, false, 0, false); } }
void player_t::TickPSprites() { DPSprite *pspr = psprites; while (pspr) { // Destroy the psprite if it's from a weapon that isn't currently selected by the player // or if it's from an inventory item that the player no longer owns. if ((pspr->Caller == nullptr || (pspr->Caller->IsKindOf(RUNTIME_CLASS(AInventory)) && barrier_cast<AInventory *>(pspr->Caller)->Owner != pspr->Owner->mo) || (pspr->Caller->IsKindOf(RUNTIME_CLASS(AWeapon)) && pspr->Caller != pspr->Owner->ReadyWeapon))) { pspr->Destroy(); } else { pspr->Tick(); } pspr = pspr->Next; } if ((health > 0) || (ReadyWeapon != nullptr && !(ReadyWeapon->WeaponFlags & WIF_NODEATHINPUT))) { if (ReadyWeapon == nullptr) { if (PendingWeapon != WP_NOCHANGE) P_BringUpWeapon(this); } else { P_CheckWeaponSwitch(this); if (WeaponState & (WF_WEAPONREADY | WF_WEAPONREADYALT)) { P_CheckWeaponFire(this); } // Check custom buttons P_CheckWeaponButtons(this); } } }
void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep) { bool brightflash = false; unsigned int i; int lightlevel=0; FColormap cm; sector_t * fakesec, fs; AActor * playermo=players[consoleplayer].camera; player_t * player=playermo->player; // this is the same as the software renderer if (!player || !r_drawplayersprites || !camera->player || (player->cheats & CF_CHASECAM) || (r_deathcamera && camera->health <= 0)) return; float bobx, boby, wx, wy; DPSprite *weapon; P_BobWeapon(camera->player, &bobx, &boby, r_TicFracF); // Interpolate the main weapon layer once so as to be able to add it to other layers. if ((weapon = camera->player->FindPSprite(PSP_WEAPON)) != nullptr) { if (weapon->firstTic) { wx = weapon->x; wy = weapon->y; } else { wx = weapon->oldx + (weapon->x - weapon->oldx) * r_TicFracF; wy = weapon->oldy + (weapon->y - weapon->oldy) * r_TicFracF; } } else { wx = 0; wy = 0; } if (gl_fixedcolormap) { lightlevel=255; cm.Clear(); fakesec = viewsector; } else { fakesec = gl_FakeFlat(viewsector, &fs, false); // calculate light level for weapon sprites lightlevel = gl_ClampLight(fakesec->lightlevel); // calculate colormap for weapon sprites if (viewsector->e->XFloor.ffloors.Size() && !glset.nocoloredspritelighting) { TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist; for(i=0;i<lightlist.Size();i++) { double lightbottom; if (i<lightlist.Size()-1) { lightbottom=lightlist[i+1].plane.ZatPoint(ViewPos); } else { lightbottom=viewsector->floorplane.ZatPoint(ViewPos); } if (lightbottom<player->viewz) { cm = lightlist[i].extra_colormap; lightlevel = gl_ClampLight(*lightlist[i].p_lightlevel); break; } } } else { cm=fakesec->ColorMap; if (glset.nocoloredspritelighting) cm.ClearColor(); } lightlevel = gl_CalcLightLevel(lightlevel, getExtraLight(), true); if (glset.lightmode == 8) { // Korshun: the way based on max possible light level for sector like in software renderer. float min_L = 36.0 / 31.0 - ((lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63 if (min_L < 0) min_L = 0; else if (min_L > 1.0) min_L = 1.0; lightlevel = (1.0 - min_L) * 255; } else { lightlevel = (2 * lightlevel + 255) / 3; } lightlevel = gl_CheckSpriteGlow(viewsector, lightlevel, playermo->Pos()); } // Korshun: fullbright fog in opengl, render weapon sprites fullbright (but don't cancel out the light color!) if (glset.brightfog && ((level.flags&LEVEL_HASFADETABLE) || cm.FadeColor != 0)) { lightlevel = 255; } PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff; ThingColor.a = 255; visstyle_t vis; vis.RenderStyle=playermo->RenderStyle; vis.Alpha=playermo->Alpha; vis.colormap = NULL; if (playermo->Inventory) { playermo->Inventory->AlterWeaponSprite(&vis); if (vis.colormap >= SpecialColormaps[0].Colormap && vis.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap && gl_fixedcolormap == CM_DEFAULT) { // this only happens for Strife's inverted weapon sprite vis.RenderStyle.Flags |= STYLEF_InvertSource; } } // Set the render parameters int OverrideShader = -1; float trans = 0.f; if (vis.RenderStyle.BlendOp >= STYLEOP_Fuzz && vis.RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub) { vis.RenderStyle.CheckFuzz(); if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz) { if (gl_fuzztype != 0) { // Todo: implement shader selection here vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent]; OverrideShader = gl_fuzztype + 4; trans = 0.99f; // trans may not be 1 here } else { vis.RenderStyle.BlendOp = STYLEOP_Shadow; } } } gl_SetRenderStyle(vis.RenderStyle, false, false); if (vis.RenderStyle.Flags & STYLEF_TransSoulsAlpha) { trans = transsouls; } else if (vis.RenderStyle.Flags & STYLEF_Alpha1) { trans = 1.f; } else if (trans == 0.f) { trans = vis.Alpha; } // now draw the different layers of the weapon gl_RenderState.EnableBrightmap(true); gl_RenderState.SetObjectColor(ThingColor); gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold); gl_RenderState.BlendEquation(GL_FUNC_ADD); // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. int oldlightmode = glset.lightmode; if (glset.lightmode == 8) glset.lightmode = 2; for(DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { if (psp->GetState() != nullptr) { FColormap cmc = cm; int ll = lightlevel; if (isBright(psp)) { if (fakesec == viewsector || in_area != area_below) { cmc.LightColor.r= cmc.LightColor.g= cmc.LightColor.b=0xff; } else { // under water areas keep most of their color for fullbright objects cmc.LightColor.r = (3 * cmc.LightColor.r + 0xff) / 4; cmc.LightColor.g = (3*cmc.LightColor.g + 0xff)/4; cmc.LightColor.b = (3*cmc.LightColor.b + 0xff)/4; } ll = 255; } // set the lighting parameters if (vis.RenderStyle.BlendOp == STYLEOP_Shadow) { gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, cmc.desaturation); } else { if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites) { gl_SetDynSpriteLight(playermo, NULL); } gl_SetColor(ll, 0, cmc, trans, true); } if (psp->firstTic) { // Can't interpolate the first tic. psp->firstTic = false; psp->oldx = psp->x; psp->oldy = psp->y; } float sx = psp->oldx + (psp->x - psp->oldx) * r_TicFracF; float sy = psp->oldy + (psp->y - psp->oldy) * r_TicFracF; if (psp->Flags & PSPF_ADDBOB) { sx += bobx; sy += boby; } if (psp->Flags & PSPF_ADDWEAPON && psp->GetID() != PSP_WEAPON) { sx += wx; sy += wy; } DrawPSprite(player, psp, sx, sy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha)); } } gl_RenderState.SetObjectColor(0xffffffff); gl_RenderState.SetDynLight(0, 0, 0); gl_RenderState.EnableBrightmap(false); glset.lightmode = oldlightmode; }