diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 35f2d0967..a44dc48d6 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,15 @@ +December 28, 2007 (Changes by Graf Zahl) +- Added a check to Wads.CheckNumForName to return -1 for names longer than + 8 characters which contain path separators. +- Fixed: Hires texture replacement must replace all matching textures, not + just the first one found. This is particularly important for icons based + on sprites. +- added a con_alpha CVAR to set the console's translucency. +- Added MartinHowe's submission for A_CustomBulletAttack aimfacing parameter. +- Added MartinHowe's submission for A_PlaySoundEx attenuation parameter. +- Fixed: Bots shouldn't target friendly monsters. +- Fixed a typo in sbarinfo.cpp (noatribox instead of noartibox.) + December 27, 2007 - Fixed cases where a larger power-of-2-sized native texture had to be allocated. (I wonder if D3D actually handles this automatically when you use diff --git a/src/b_think.cpp b/src/b_think.cpp index 059876c08..3de21e983 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -403,6 +403,6 @@ void DCajunMaster::Set_enemy (AActor *actor) *enemy = oldenemy; //Try go for last (it will be NULL if there wasn't anyone) } //Verify that that enemy is really something alive that bot can kill. - if (*enemy && ((*enemy)->health < 0 || !((*enemy)->flags&MF_SHOOTABLE))) + if (*enemy && (((*enemy)->health < 0 || !((*enemy)->flags&MF_SHOOTABLE)) || actor->IsFriend(*enemy))) *enemy = NULL; } diff --git a/src/c_console.cpp b/src/c_console.cpp index 97439a366..c18ce93da 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -62,6 +62,7 @@ #include "doomstat.h" #include "d_gui.h" #include "v_video.h" +#include "vectors.h" #include "gi.h" @@ -157,6 +158,12 @@ CUSTOM_CVAR (Int, con_scaletext, 0, CVAR_ARCHIVE) // Scale notify text at high if (self > 2) self = 2; } +CUSTOM_CVAR(Float, con_alpha, 0.75f, CVAR_ARCHIVE) +{ + if (self < 0.f) self = 0.f; + if (self > 1.f) self = 1.f; +} + // Command to run when Ctrl-D is pressed at start of line CVAR (String, con_ctrl_d, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) @@ -1138,7 +1145,7 @@ void C_DrawConsole (bool hw2d) DTA_DestWidth, screen->GetWidth(), DTA_DestHeight, screen->GetHeight(), DTA_ColorOverlay, conshade, - DTA_Alpha, hw2d ? FRACUNIT*3/4 : FRACUNIT, + DTA_Alpha, hw2d ? FLOAT2FIXED(con_alpha) : FRACUNIT, DTA_Masked, false, TAG_DONE); if (conline && visheight < screen->GetHeight()) diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp index d47558fcb..1e224f561 100644 --- a/src/g_shared/sbarinfo.cpp +++ b/src/g_shared/sbarinfo.cpp @@ -522,7 +522,7 @@ void SBarInfo::ParseSBarInfoBlock(SBarInfoBlock &block) { cmd.flags += DRAWINVENTORYBAR_ALWAYSSHOW; } - else if(SC_Compare("noatribox")) + else if(SC_Compare("noartibox")) { cmd.flags += DRAWINVENTORYBAR_NOARTIBOX; } diff --git a/src/r_data.cpp b/src/r_data.cpp index 09bc7f843..b72e3373f 100644 --- a/src/r_data.cpp +++ b/src/r_data.cpp @@ -147,6 +147,46 @@ int FTextureManager::CheckForTexture (const char *name, int usetype, BITFIELD fl return -1; } +int FTextureManager::ListTextures (const char *name, TArray &list) +{ + int i; + + if (name == NULL || name[0] == '\0') + { + return 0; + } + // [RH] Doom counted anything beginning with '-' as "no texture". + // Hopefully nobody made use of that and had textures like "-EMPTY", + // because -NOFLAT- is a valid graphic for ZDoom. + if (name[0] == '-' && name[1] == '\0') + { + return 0; + } + i = HashFirst[MakeKey (name) % HASH_SIZE]; + + while (i != HASH_END) + { + const FTexture *tex = Textures[i].Texture; + + if (stricmp (tex->Name, name) == 0) + { + // NULL textures must be ignored. + if (tex->UseType!=FTexture::TEX_Null) + { + int j; + for(j = 0; j < list.Size(); j++) + { + // Check for overriding definitions from newer WADs + if (Textures[list[j]].Texture->UseType == tex->UseType) break; + } + if (j==list.Size()) list.Push(i); + } + } + i = Textures[i].HashNext; + } + return list.Size(); +} + int FTextureManager::GetTexture (const char *name, int usetype, BITFIELD flags) { int i; @@ -312,6 +352,7 @@ void FTextureManager::AddHiresTextures () int firsttx = Wads.CheckNumForName ("HI_START"); int lasttx = Wads.CheckNumForName ("HI_END"); char name[9]; + TArray tlist; if (firsttx == -1 || lasttx == -1) { @@ -322,38 +363,44 @@ void FTextureManager::AddHiresTextures () for (firsttx += 1; firsttx < lasttx; ++firsttx) { + tlist.Clear(); Wads.GetLumpName (name, firsttx); if (Wads.CheckNumForName (name, ns_hires) == firsttx) { - FTexture * newtex = FTexture::CreateTexture (firsttx, FTexture::TEX_Any); - if (newtex != NULL) + int amount = ListTextures(name, tlist); + if (amount == 0) { - int oldtexno = CheckForTexture(name, FTexture::TEX_Wall, TEXMAN_Overridable|TEXMAN_TryAny); - - if (oldtexno<0) - { - oldtexno = AddPatch(name); - } - newtex->bWorldPanning = true; - if (oldtexno<0) - { - // A texture with this name does not yet exist - newtex->UseType=FTexture::TEX_Override; - AddTexture(newtex); - } - else - { - FTexture * oldtex = Textures[oldtexno].Texture; - - // Replace the entire texture and adjust the scaling and offset factors. - newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); - newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); - ReplaceTexture(oldtexno, newtex, true); - } - StartScreen->Progress(); + int oldtex = AddPatch(name); + if (oldtex >= 0) tlist.Push(oldtex); } + if (tlist.Size() == 0) + { + // A texture with this name does not yet exist + FTexture * newtex = FTexture::CreateTexture (firsttx, FTexture::TEX_Any); + newtex->UseType=FTexture::TEX_Override; + AddTexture(newtex); + } + else + { + for(int i = 0; i < tlist.Size(); i++) + { + FTexture * newtex = FTexture::CreateTexture (firsttx, FTexture::TEX_Any); + if (newtex != NULL) + { + int oldtexno = tlist[i]; + FTexture * oldtex = Textures[oldtexno].Texture; + + // Replace the entire texture and adjust the scaling and offset factors. + newtex->bWorldPanning = true; + newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); + newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); + newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); + ReplaceTexture(oldtexno, newtex, true); + } + } + } + StartScreen->Progress(); } } } @@ -371,6 +418,7 @@ void FTextureManager::LoadHiresTex() bool is32bit; int width, height; int type, mode; + TArray tlist; lastLump = 0; src[8] = '\0'; @@ -392,30 +440,50 @@ void FTextureManager::LoadHiresTex() sc_String[8]=0; - int tex = TexMan.CheckForTexture(sc_String, type, mode); - - if (tex<0) + tlist.Clear(); + int amount = ListTextures(sc_String, tlist); + if (amount == 0) { - tex= AddPatch(sc_String); + int oldtex = AddPatch(sc_String); + if (oldtex >= 0) tlist.Push(oldtex); } + FName texname = sc_String; SC_MustGetString(); int lumpnum = Wads.CheckNumForFullName(sc_String); if (lumpnum < 0) lumpnum = Wads.CheckNumForName(sc_String, ns_graphics); - if (tex>0) + if (tlist.Size() == 0) { - FTexture * oldtex = TexMan[tex]; - FTexture * newtex = FTexture::CreateTexture (lumpnum, FTexture::TEX_Any); - - if (newtex != NULL) + Printf("Attempting to remap non-existent texture %s to %s\n", + texname.GetChars(), sc_String); + } + else + { + for(int i = 0; i < tlist.Size(); i++) { - // Replace the entire texture and adjust the scaling and offset factors. - newtex->bWorldPanning = true; - newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); - newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); - newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); - ReplaceTexture(tex, newtex, true); + FTexture * oldtex = Textures[tlist[i]].Texture; + int sl; + + // only replace matching types. For sprites also replace any MiscPatches + // based on the same lump. These can be created for icons. + if (oldtex->UseType == type || type == FTexture::TEX_Any || + (mode == TEXMAN_Overridable && oldtex->UseType == FTexture::TEX_Override) || + (type == FTexture::TEX_Sprite && oldtex->UseType == FTexture::TEX_MiscPatch && + (sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites) + ) + { + FTexture * newtex = FTexture::CreateTexture (lumpnum, FTexture::TEX_Any); + if (newtex != NULL) + { + // Replace the entire texture and adjust the scaling and offset factors. + newtex->bWorldPanning = true; + newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); + newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); + newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); + ReplaceTexture(tlist[i], newtex, true); + } + } } } } diff --git a/src/r_data.h b/src/r_data.h index a30b2bd86..a3b6995ef 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -53,6 +53,8 @@ public: const BYTE *GetPixels (); void Unload (); + int GetSourceLump() { return SourceLump; } + protected: int SourceLump; BYTE *Pixels; @@ -121,6 +123,8 @@ public: const BYTE *GetPixels (); void Unload (); + int GetSourceLump() { return SourceLump; } + protected: int SourceLump; BYTE *Pixels; @@ -162,6 +166,8 @@ public: const BYTE *GetPixels (); void Unload (); + int GetSourceLump() { return SourceLump; } + protected: static bool Check(FileReader & file); static FTexture *Create(FileReader & file, int lumpnum); @@ -187,6 +193,8 @@ public: void Unload (); void MakeTexture (); + int GetSourceLump() { return LumpNum; } + private: static bool Check(FileReader & file); @@ -213,6 +221,8 @@ public: const BYTE *GetPixels (); void Unload (); + int GetSourceLump() { return SourceLump; } + protected: static bool Check(FileReader & file); @@ -242,6 +252,7 @@ public: FTextureFormat GetFormat (); int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); bool UseBasePalette(); + int GetSourceLump() { return SourceLump; } static FTexture *CreateFromFile (PNGHandle *png, const FString &filename); @@ -279,6 +290,7 @@ public: const BYTE *GetPixels (); void Unload (); FTextureFormat GetFormat (); + int GetSourceLump() { return SourceLump; } protected: static bool Check (FileReader &file); @@ -324,6 +336,7 @@ public: FTextureFormat GetFormat (); int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); bool UseBasePalette(); + int GetSourceLump() { return SourceLump; } protected: @@ -375,6 +388,7 @@ public: int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); bool UseBasePalette(); + int GetSourceLump() { return SourceLump; } protected: int SourceLump; @@ -431,6 +445,7 @@ public: int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); bool UseBasePalette(); + int GetSourceLump() { return SourceLump; } protected: int SourceLump; @@ -463,6 +478,7 @@ public: const BYTE *GetPixels (); void Unload (); bool CheckModified (); + int GetSourceLump() { return SourcePic->GetSourceLump(); } protected: FTexture *SourcePic; diff --git a/src/r_defs.h b/src/r_defs.h index d4eca46b5..c37a9837a 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -667,6 +667,7 @@ public: virtual int CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y); virtual bool UseBasePalette(); + virtual int GetSourceLump() { return -1; } virtual void Unload () = 0; @@ -794,6 +795,7 @@ public: int CheckForTexture (const char *name, int usetype, BITFIELD flags=TEXMAN_TryAny); int GetTexture (const char *name, int usetype, BITFIELD flags=0); + int ListTextures (const char *name, TArray &list); void WriteTexture (FArchive &arc, int picnum); int ReadTexture (FArchive &arc); diff --git a/src/thingdef_codeptr.cpp b/src/thingdef_codeptr.cpp index 20ffd042e..053066d27 100644 --- a/src/thingdef_codeptr.cpp +++ b/src/thingdef_codeptr.cpp @@ -308,12 +308,23 @@ void A_StopSound(AActor * self) void A_PlaySoundEx (AActor *self) { - int index = CheckIndex(3); + int index = CheckIndex(4); if (index < 0) return; int soundid = StateParameters[index]; ENamedName channel = ENamedName(StateParameters[index + 1]); INTBOOL looping = StateParameters[index + 2]; + int attenuation_raw = EvalExpressionI(StateParameters[index + 3], self); + + int attenuation; + switch (attenuation_raw) + { + case -1: attenuation=ATTN_STATIC; break; // drop off rapidly + default: + case 0: attenuation=ATTN_NORM; break; // normal + case 1: attenuation=ATTN_NONE; break; // full volume + case 2: attenuation=ATTN_SURROUND; break; // full volume surround + } if (channel < NAME_Auto || channel > NAME_SoundSlot7) { @@ -322,13 +333,13 @@ void A_PlaySoundEx (AActor *self) if (!looping) { - S_SoundID (self, channel - NAME_Auto, soundid, 1, ATTN_NORM); + S_SoundID (self, channel - NAME_Auto, soundid, 1, attenuation); } else { if (!S_IsActorPlayingSomething (self, channel - NAME_Auto, soundid)) { - S_LoopedSoundID (self, channel - NAME_Auto, soundid, 1, ATTN_NORM); + S_LoopedSoundID (self, channel - NAME_Auto, soundid, 1, attenuation); } } } @@ -811,7 +822,7 @@ void A_CustomMissile(AActor * self) //========================================================================== void A_CustomBulletAttack (AActor *self) { - int index=CheckIndex(6); + int index=CheckIndex(7); if (index<0) return; angle_t Spread_XY=angle_t(EvalExpressionF (StateParameters[index], self) * ANGLE_1); @@ -820,6 +831,7 @@ void A_CustomBulletAttack (AActor *self) int DamagePerBullet=EvalExpressionI (StateParameters[index+3], self); ENamedName PuffType=(ENamedName)StateParameters[index+4]; fixed_t Range = fixed_t(EvalExpressionF (StateParameters[index+5], self) * FRACUNIT); + bool AimFacing = !!EvalExpressionI (StateParameters[index+6], self); if(Range==0) Range=MISSILERANGE; @@ -829,9 +841,9 @@ void A_CustomBulletAttack (AActor *self) int bslope; const PClass *pufftype; - if (self->target) + if (self->target || AimFacing) { - A_FaceTarget (self); + if (!AimFacing) A_FaceTarget (self); bangle = self->angle; pufftype = PClass::FindClass(PuffType); diff --git a/src/w_wad.cpp b/src/w_wad.cpp index 854cfd3f8..53e645004 100644 --- a/src/w_wad.cpp +++ b/src/w_wad.cpp @@ -827,6 +827,13 @@ int FWadCollection::CheckNumForName (const char *name, int space) return -1; } + // Let's not search for names that are longer than 8 characters and contain path separators + // They are almost certainly full path names passed to this function. + if (strlen(name) > 8 && strpbrk(name, "/.")) + { + return -1; + } + uppercopy (uname, name); i = FirstLumpIndex[LumpNameHash (uname) % NumLumps]; diff --git a/wadsrc/decorate/nativeclasses.txt b/wadsrc/decorate/nativeclasses.txt index 4b2a25c5d..a50b22f4a 100644 --- a/wadsrc/decorate/nativeclasses.txt +++ b/wadsrc/decorate/nativeclasses.txt @@ -124,12 +124,12 @@ class Actor extends Thinker action native A_FLoopActiveSound(); action native A_LoopActiveSound(); action native A_StopSound(); - action native A_PlaySoundEx(sound whattoplay, coerce name slot, optional bool looping); + action native A_PlaySoundEx(sound whattoplay, coerce name slot, optional bool looping, optional eval int attenuation); action native A_StopSoundEx(coerce name slot); action native A_SeekerMissile(eval int threshold, eval int turnmax); action native A_Jump(eval int chance, state label, ...); action native A_CustomMissile(class missiletype, eval float spawnheight, eval int spawnofs_xy, optional eval float angle, optional eval int flags, optional eval float pitch); - action native A_CustomBulletAttack(eval float spread_xy, eval float spread_z, eval int numbullets, eval int damageperbullet, optional class pufftype, optional eval float range); + action native A_CustomBulletAttack(eval float spread_xy, eval float spread_z, eval int numbullets, eval int damageperbullet, optional class pufftype, optional eval float range, optional eval bool aimfacing); action native A_CustomRailgun(eval int damage, optional eval int spawnofs_xy, optional color color1, optional color color2, optional eval bool silent, optional eval bool aim, optional eval float maxdiff, optional class pufftype); action native A_JumpIfHealthLower(eval int health, state label); action native A_JumpIfCloser(eval float distance, state label);