Update to ZDoom r1425:

- Added MF5_CANTSEEK flag to prevent seeker missiles from homing in on
  certain actors and added an option to APowerInvisibility to set this
  flag when active.
- Added map specific automap backgrounds.
- Fixed: Voodoo dolls did not play a sound when dying.
- Added colorized error messages to DECORATE and made a few more error
  conditions that do not block further parsing not immediately abort.
- Made all errors in CreateNewActor not immediately fatal so that the
  rest of the DECORATE lump can be parsed normally to look for more errors.
- Fixed: Defining classes with the same name as their immediate base class
  was legal. It should not be allowed that a class has another one with the
  same name in its ancestry.
- Fixed: Formatting of the intermission screen on Heretic, Hexen and Strife
  was broken. Changed it to use WI_Drawpercent which does it properly and
  also allows showing percentage in these games now.
- Fixed: The MAPINFO parser ignored missing terminating braces of the last
  block in the file.
- Moved the V_InitFontColors() call earlier in the startup sequence so that
  colored error messages appear colored in the startup window. Also lightened
  up the "Flat" red to contrast better on the startup background.
- Changed I_InitInput() to acquire the IDirectInput8A interface by using
  DirectInput8Create() instead of CoCreateInstance(). This allows the Steam
  GameOverlayRenderer.dll to properly hook it.
- Stopped sending double the number of wheel events as appropriate to the
  console under Linux.
- Added middle mouse button selection pasting for X systems.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@301 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-02-20 09:24:51 +00:00
parent b9d95ad3ea
commit cacebde16e
34 changed files with 294 additions and 128 deletions

View file

@ -1,3 +1,35 @@
February 14, 2009 (Changes by Graf Zahl)
- Added MF5_CANTSEEK flag to prevent seeker missiles from homing in on
certain actors and added an option to APowerInvisibility to set this
flag when active.
- Added map specific automap backgrounds.
- Fixed: Voodoo dolls did not play a sound when dying.
- Added colorized error messages to DECORATE and made a few more error
conditions that do not block further parsing not immediately abort.
- Made all errors in CreateNewActor not immediately fatal so that the
rest of the DECORATE lump can be parsed normally to look for more errors.
- Fixed: Defining classes with the same name as their immediate base class
was legal. It should not be allowed that a class has another one with the
same name in its ancestry.
- Fixed: Formatting of the intermission screen on Heretic, Hexen and Strife
was broken. Changed it to use WI_Drawpercent which does it properly and
also allows showing percentage in these games now.
- Fixed: The MAPINFO parser ignored missing terminating braces of the last
block in the file.
February 10, 2009
- Moved the V_InitFontColors() call earlier in the startup sequence so that
colored error messages appear colored in the startup window. Also lightened
up the "Flat" red to contrast better on the startup background.
February 9, 2009
- Changed I_InitInput() to acquire the IDirectInput8A interface by using
DirectInput8Create() instead of CoCreateInstance(). This allows the Steam
GameOverlayRenderer.dll to properly hook it.
- Stopped sending double the number of wheel events as appropriate to the
console under Linux.
- Added middle mouse button selection pasting for X systems.
February 8, 2009 (Changes by Graf Zahl)
- Fixed parsing for MustConfirm key in skill parser.
- Converted internal MAPINFOs to new syntax.
@ -5,7 +37,7 @@ February 8, 2009 (Changes by Graf Zahl)
- Restored Dehacked music name replacement.
February 7, 2009
- Added GUICapture mouse events for Win32.
- Added GUICapture mouse button events for Win32.
- Changed I_GetFromClipboard() to return an FString.
- Added GTK+-based clipboard support for Linux.
- Fixed: Most Linux filesystems do not fill in d_type for scandir(), so we

View file

@ -305,6 +305,7 @@ enum
MF5_SUMMONEDMONSTER = 0x02000000, // To mark the friendly Minotaur. Hopefully to be generalized later.
MF5_NOVERTICALMELEERANGE=0x04000000,// Does not check vertical distance for melee range
MF5_BRIGHT = 0x08000000, // Actor is always rendered fullbright
MF5_CANTSEEK = 0x10000000, // seeker missiles cannot home in on this actor
// --- mobj.renderflags ---

View file

@ -798,7 +798,9 @@ void AM_loadPics ()
marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch);
}
mapback = TexMan.CheckForTexture("AUTOPAGE", FTexture::TEX_MiscPatch);
const char *autopage = level.info->mapbg[0] == 0? "AUTOPAGE" : (const char*)level.info->mapbg[0];
mapback = TexMan.CheckForTexture(autopage, FTexture::TEX_MiscPatch);
}
bool AM_clearMarks ()

View file

@ -108,6 +108,7 @@ static int TopLine, InsertLine;
static char *BufferRover = ConsoleBuffer;
static void ClearConsole ();
static void C_PasteText(FString clip, BYTE *buffer, int len);
struct GameAtExit
{
@ -1735,42 +1736,22 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len)
buffer[2 + buffer[0]] = 0;
I_PutInClipboard ((char *)&buffer[2]);
}
break;
}
else
{ // paste from clipboard
FString clip = I_GetFromClipboard ();
if (clip.IsNotEmpty())
{
// Only paste the first line.
long brk = clip.IndexOfAny("\r\n\b");
int cliplen = brk >= 0 ? brk : clip.Len();
// Make sure there's room for the whole thing.
if (buffer[0] + cliplen > len)
{
cliplen = len - buffer[0];
}
if (cliplen > 0)
{
if (buffer[1] < buffer[0])
{
memmove (&buffer[2 + buffer[1] + cliplen],
&buffer[2 + buffer[1]], buffer[0] - buffer[1]);
}
memcpy (&buffer[2 + buffer[1]], clip, cliplen);
buffer[0] += cliplen;
buffer[1] += cliplen;
makestartposgood ();
HistPos = NULL;
}
}
break;
C_PasteText(I_GetFromClipboard(false), buffer, len);
}
break;
}
break;
}
break;
#ifdef unix
case EV_GUI_MButtonDown:
C_PasteText(I_GetFromClipboard(true), buffer, len);
break;
#endif
}
// Ensure that the cursor is always visible while typing
CursorTicker = C_BLINKRATE;
@ -1778,6 +1759,36 @@ static bool C_HandleKey (event_t *ev, BYTE *buffer, int len)
return true;
}
static void C_PasteText(FString clip, BYTE *buffer, int len)
{
if (clip.IsNotEmpty())
{
// Only paste the first line.
long brk = clip.IndexOfAny("\r\n\b");
int cliplen = brk >= 0 ? brk : clip.Len();
// Make sure there's room for the whole thing.
if (buffer[0] + cliplen > len)
{
cliplen = len - buffer[0];
}
if (cliplen > 0)
{
if (buffer[1] < buffer[0])
{
memmove (&buffer[2 + buffer[1] + cliplen],
&buffer[2 + buffer[1]], buffer[0] - buffer[1]);
}
memcpy (&buffer[2 + buffer[1]], clip, cliplen);
buffer[0] += cliplen;
buffer[1] += cliplen;
makestartposgood ();
HistPos = NULL;
}
}
}
bool C_Responder (event_t *ev)
{
if (ev->type != EV_GUI_Event ||

View file

@ -152,7 +152,7 @@ bool CT_Responder (event_t *ev)
}
else if (ev->data1 == 'V' && (ev->data3 & GKM_CTRL))
{
CT_PasteChat(I_GetFromClipboard());
CT_PasteChat(I_GetFromClipboard(false));
}
}
else if (ev->subtype == EV_GUI_Char)
@ -169,10 +169,12 @@ bool CT_Responder (event_t *ev)
}
return true;
}
#ifdef unix
else if (ev->subtype == EV_GUI_MButtonDown)
{
CT_PasteChat(I_GetFromClipboard());
CT_PasteChat(I_GetFromClipboard(true));
}
#endif
}
return false;
@ -186,7 +188,7 @@ bool CT_Responder (event_t *ev)
void CT_PasteChat(const char *clip)
{
if (clip != NULL)
if (clip != NULL && *clip != '\0')
{
// Only paste the first line.
while (*clip != '\0')

View file

@ -2340,6 +2340,8 @@ void D_DoomMain (void)
// [RH] Initialize localizable strings.
GStrings.LoadStrings (false);
V_InitFontColors ();
// [RH] Moved these up here so that we can do most of our
// startup output in a fullscreen console.

View file

@ -73,7 +73,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer)
// adjust direction
dest = self->tracer;
if (!dest || dest->health <= 0 || self->Speed == 0)
if (!dest || dest->health <= 0 || self->Speed == 0 || (dest->flags5 & MF5_CANTSEEK))
return;
// change angle

View file

@ -95,6 +95,7 @@ struct FMapInfoParser
bool CheckNumber();
bool CheckFloat();
void SkipToNext();
void CheckEndOfFile(const char *block);
};
#define DEFINE_MAP_OPTION(name, old) \
@ -284,6 +285,7 @@ struct level_info_t
FString SoundInfo;
FString SndSeq;
char bordertexture[9];
char mapbg[9];
float teamdamage;

View file

@ -408,7 +408,7 @@ void FMapInfoParser::ParseOpenBrace()
switch(format_type)
{
default:
format_type = sc.CheckString("{")? FMT_New : FMT_Old;
format_type = sc.CheckString("{") ? FMT_New : FMT_Old;
if (format_type == FMT_New)
sc.SetCMode(true);
break;
@ -541,6 +541,21 @@ void FMapInfoParser::SkipToNext()
}
}
//==========================================================================
//
// checks if the current block was properly terminated
//
//==========================================================================
void FMapInfoParser::CheckEndOfFile(const char *block)
{
if (format_type == FMT_New && !sc.Compare("}"))
{
sc.ScriptError("Unexpected end of file in %s definition", block);
}
}
//==========================================================================
//
// ParseLookupname
@ -715,6 +730,7 @@ void FMapInfoParser::ParseCluster()
break;
}
}
CheckEndOfFile("cluster");
}
@ -1191,6 +1207,13 @@ DEFINE_MAP_OPTION(teamdamage, true)
info->teamdamage = parse.sc.Float;
}
DEFINE_MAP_OPTION(mapbackground, true)
{
parse.ParseAssign();
parse.ParseLumpOrTextureName(info->mapbg);
}
//==========================================================================
//
// All flag based map options
@ -1421,6 +1444,7 @@ void FMapInfoParser::ParseMapDefinition(level_info_t &info)
}
}
}
CheckEndOfFile("map");
}
@ -1620,6 +1644,7 @@ void FMapInfoParser::ParseEpisodeInfo ()
break;
}
}
CheckEndOfFile("episode");
if (extended && !(gameinfo.flags & GI_MENUHACK_EXTENDED))
{ // If the episode is for the extended Heretic, but this is

View file

@ -540,6 +540,22 @@ PalEntry APowerStrength::GetBlend ()
IMPLEMENT_CLASS (APowerInvisibility)
//===========================================================================
//
// APowerInvisibility :: CommonInit
//
// stuff that's done for all subclasses
//
//===========================================================================
void APowerInvisibility::CommonInit()
{
Owner->flags |= MF_SHADOW;
// transfer seeker missile blocking (but only if the owner does not already have this flag
if (!(Owner->flags5 & MF5_CANTSEEK) && (flags5 & MF5_CANTSEEK)) Owner->flags5 |= MF5_CANTSEEK;
else flags &=~MF5_CANTSEEK;
}
//===========================================================================
//
// APowerInvisibility :: InitEffect
@ -548,11 +564,16 @@ IMPLEMENT_CLASS (APowerInvisibility)
void APowerInvisibility::InitEffect ()
{
Owner->flags |= MF_SHADOW;
CommonInit();
Owner->alpha = FRACUNIT/5;
Owner->RenderStyle = STYLE_OptFuzzy;
}
//===========================================================================
//
// APowerInvisibility :: DoEffect
//
//===========================================================================
void APowerInvisibility::DoEffect ()
{
Super::DoEffect();
@ -571,6 +592,7 @@ void APowerInvisibility::EndEffect ()
{
if (Owner != NULL)
{
if (flags5 & MF5_CANTSEEK) Owner->flags5 &= ~MF5_CANTSEEK;
Owner->flags &= ~MF_SHADOW;
Owner->flags3 &= ~MF3_GHOST;
Owner->RenderStyle = STYLE_Normal;
@ -628,7 +650,7 @@ IMPLEMENT_CLASS (APowerGhost)
void APowerGhost::InitEffect ()
{
Owner->flags |= MF_SHADOW;
CommonInit();
Owner->flags3 |= MF3_GHOST;
Owner->alpha = HR_SHADOW;
Owner->RenderStyle = STYLE_Translucent;
@ -705,7 +727,7 @@ bool APowerShadow::HandlePickup (AInventory *item)
void APowerShadow::InitEffect ()
{
Owner->flags |= MF_SHADOW;
CommonInit();
Owner->alpha = special1 == 0 ? TRANSLUC25 : 0;
Owner->RenderStyle = STYLE_Translucent;
}

View file

@ -77,6 +77,7 @@ class APowerInvisibility : public APowerup
{
DECLARE_CLASS (APowerInvisibility, APowerup)
protected:
void CommonInit ();
void InitEffect ();
void DoEffect ();
void EndEffect ();

View file

@ -309,7 +309,7 @@ void DSBarInfo::Tick ()
oldHealth += clamp((health - oldHealth), 1, script->interpolationSpeed);
}
}
AInventory *armor = CPlayer->mo->FindInventory<ABasicArmor>();
AInventory *armor = CPlayer->mo != NULL? CPlayer->mo->FindInventory<ABasicArmor>() : NULL;
if(armor == NULL)
{
oldArmor = 0;

View file

@ -225,6 +225,7 @@ void FMapInfoParser::ParseSkill ()
break;
}
}
CheckEndOfFile("skill");
for(unsigned int i = 0; i < AllSkills.Size(); i++)
{
if (AllSkills[i].Name == skill.Name)

View file

@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer2)
dest = self->tracer;
if (dest == NULL || dest->health <= 0 || self->Speed == 0)
if (!dest || dest->health <= 0 || self->Speed == 0 || (dest->flags5 & MF5_CANTSEEK))
return;
// change angle

View file

@ -71,6 +71,7 @@ EXTERN_CVAR (Color, am_wallcolor)
EXTERN_CVAR (Color, am_fdwallcolor)
EXTERN_CVAR (Color, am_cdwallcolor)
EXTERN_CVAR (Float, spc_amp)
EXTERN_CVAR (Bool, wi_percents)
FString WeaponSection;
@ -638,6 +639,8 @@ void FGameConfigFile::SetRavenDefaults (bool isHexen)
color.ResetToDefault ();
}
val.Bool = false;
wi_percents.SetGenericRepDefault (val, CVAR_Bool);
val.Bool = true;
con_centernotify.SetGenericRepDefault (val, CVAR_Bool);
snd_pitched.SetGenericRepDefault (val, CVAR_Bool);

View file

@ -1287,7 +1287,7 @@ bool P_SeekerMissile (AActor *actor, angle_t thresh, angle_t turnMax)
AActor *target;
target = actor->tracer;
if (target == NULL || actor->Speed == 0)
if (target == NULL || actor->Speed == 0 || (target->flags5 & MF5_CANTSEEK))
{
return false;
}

View file

@ -3650,8 +3650,6 @@ void P_SetupLevel (char *lumpname, int position)
// set up world state
P_SpawnSpecials ();
P_InitTagLists();
// This must be done BEFORE the PolyObj Spawn!!!
gl_PreprocessLevel();

View file

@ -1221,7 +1221,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream)
if (self->player == NULL || self->DeathSound != 0)
{
S_Sound (self, CHAN_VOICE, self->DeathSound, 1, ATTN_NORM);
if (self->DeathSound != 0)
{
S_Sound (self, CHAN_VOICE, self->DeathSound, 1, ATTN_NORM);
}
else
{
S_Sound (self, CHAN_VOICE, "*death", 1, ATTN_NORM);
}
return;
}

View file

@ -1013,7 +1013,7 @@ void STACK_ARGS FScanner::ScriptMessage (const char *message, ...)
va_end (arglist);
}
Printf (TEXTCOLOR_RED"Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(),
Printf (TEXTCOLOR_RED"Script error, \"%s\" line %d:\n"TEXTCOLOR_RED"%s\n", ScriptName.GetChars(),
AlreadyGot? AlreadyGotLine : Line, composed.GetChars());
}
@ -1087,6 +1087,7 @@ void STACK_ARGS FScriptPosition::Message (int severity, const char *message, ...
va_end (arglist);
}
const char *type = "";
const char *color;
int level = PRINT_HIGH;
switch (severity)
@ -1096,29 +1097,34 @@ void STACK_ARGS FScriptPosition::Message (int severity, const char *message, ...
case MSG_WARNING:
type = "warning";
color = TEXTCOLOR_YELLOW;
break;
case MSG_ERROR:
ErrorCounter++;
type = "error";
color = TEXTCOLOR_RED;
break;
case MSG_MESSAGE:
case MSG_DEBUG:
type = "message";
color = TEXTCOLOR_GREEN;
break;
case MSG_DEBUGLOG:
case MSG_LOG:
type = "message";
level = PRINT_LOG;
color = "";
break;
case MSG_FATAL:
I_Error ("Script error, \"%s\" line %d:\n%s\n",
FileName.GetChars(), ScriptLine, composed.GetChars());
}
Printf (level, "Script %s, \"%s\" line %d:\n%s\n",
type, FileName.GetChars(), ScriptLine, composed.GetChars());
Printf (level, "%sScript %s, \"%s\" line %d:\n%s%s\n",
color, type, FileName.GetChars(), ScriptLine, color, composed.GetChars());
}

View file

@ -227,7 +227,8 @@ enum
MSG_ERROR,
MSG_DEBUG,
MSG_LOG,
MSG_DEBUGLOG
MSG_DEBUGLOG,
MSG_MESSAGE
};
//==========================================================================

View file

@ -285,14 +285,17 @@ static void WheelMoved(event_t *event)
{
if (GUICapture)
{
SDLMod mod = SDL_GetModState();
event->type = EV_GUI_Event;
event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown;
event->data1 = 0;
event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
((mod & KMOD_CTRL) ? GKM_CTRL : 0) |
((mod & KMOD_ALT) ? GKM_ALT : 0);
D_PostEvent(event);
if (event->type != EV_KeyUp)
{
SDLMod mod = SDL_GetModState();
event->type = EV_GUI_Event;
event->subtype = event->data1 == KEY_MWHEELUP ? EV_GUI_WheelUp : EV_GUI_WheelDown;
event->data1 = 0;
event->data3 = ((mod & KMOD_SHIFT) ? GKM_SHIFT : 0) |
((mod & KMOD_CTRL) ? GKM_CTRL : 0) |
((mod & KMOD_ALT) ? GKM_ALT : 0);
D_PostEvent(event);
}
}
else
{
@ -376,41 +379,51 @@ void MessagePump (const SDL_Event &sev)
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
/* These button mappings work with my Gentoo system using the
* evdev driver and a Logitech MX510 mouse. Whether or not they
* carry over to other Linux systems, I have no idea, but I sure
* hope so. (Though buttons 11 and 12 are kind of useless, since
* they also trigger buttons 4 and 5.)
*/
switch (sev.button.button)
if (!GUICapture || sev.button.button == 4 || sev.button.button == 5)
{
case 1: event.data1 = KEY_MOUSE1; break;
case 2: event.data1 = KEY_MOUSE3; break;
case 3: event.data1 = KEY_MOUSE2; break;
case 4: event.data1 = KEY_MWHEELUP; break;
case 5: event.data1 = KEY_MWHEELDOWN; break;
case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */
case 7: event.data1 = KEY_MOUSE5; break; /* ditto */
case 8: event.data1 = KEY_MOUSE4; break;
case 9: event.data1 = KEY_MOUSE5; break;
case 10: event.data1 = KEY_MOUSE6; break;
case 11: event.data1 = KEY_MOUSE7; break;
case 12: event.data1 = KEY_MOUSE8; break;
default: printf("SDL mouse button %s %d\n",
sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break;
event.type = sev.type == SDL_MOUSEBUTTONDOWN ? EV_KeyDown : EV_KeyUp;
/* These button mappings work with my Gentoo system using the
* evdev driver and a Logitech MX510 mouse. Whether or not they
* carry over to other Linux systems, I have no idea, but I sure
* hope so. (Though buttons 11 and 12 are kind of useless, since
* they also trigger buttons 4 and 5.)
*/
switch (sev.button.button)
{
case 1: event.data1 = KEY_MOUSE1; break;
case 2: event.data1 = KEY_MOUSE3; break;
case 3: event.data1 = KEY_MOUSE2; break;
case 4: event.data1 = KEY_MWHEELUP; break;
case 5: event.data1 = KEY_MWHEELDOWN; break;
case 6: event.data1 = KEY_MOUSE4; break; /* dunno; not generated by my mouse */
case 7: event.data1 = KEY_MOUSE5; break; /* ditto */
case 8: event.data1 = KEY_MOUSE4; break;
case 9: event.data1 = KEY_MOUSE5; break;
case 10: event.data1 = KEY_MOUSE6; break;
case 11: event.data1 = KEY_MOUSE7; break;
case 12: event.data1 = KEY_MOUSE8; break;
default: printf("SDL mouse button %s %d\n",
sev.type == SDL_MOUSEBUTTONDOWN ? "down" : "up", sev.button.button); break;
}
if (event.data1 != 0)
{
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN)
{
WheelMoved(&event);
}
else
{
D_PostEvent(&event);
}
}
}
if (event.data1 != 0)
else if (sev.button.button >= 1 && sev.button.button <= 3)
{
//DIKState[ActiveDIKState][event.data1] = (event.type == EV_KeyDown);
if (event.data1 == KEY_MWHEELUP || event.data1 == KEY_MWHEELDOWN)
{
WheelMoved(&event);
}
else
{
D_PostEvent(&event);
}
event.type = EV_GUI_Event;
event.subtype = sev.type == SDL_MOUSEBUTTONDOWN ? EV_GUI_LButtonDown : EV_GUI_LButtonUp;
event.subtype += (sev.button.button - 1) * 3;
D_PostEvent(&event);
}
break;

View file

@ -2,7 +2,7 @@
#define __I_INPUT_H__
void I_PutInClipboard (const char *str);
FString I_GetFromClipboard ();
FString I_GetFromClipboard (bool use_primary_selection);
struct GUIDName
{

View file

@ -587,21 +587,24 @@ void I_PutInClipboard (const char *str)
{
gtk_clipboard_set_text(clipboard, str, -1);
}
/* Should I? I don't know. It's not actually a selection.
clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
if (clipboard != NULL)
{
gtk_clipboard_set_text(clipboard, str, -1);
}
*/
}
#endif
}
FString I_GetFromClipboard ()
FString I_GetFromClipboard (bool use_primary_selection)
{
#ifndef NO_GTK
if (GtkAvailable)
{
GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
GtkClipboard *clipboard = gtk_clipboard_get(use_primary_selection ?
GDK_SELECTION_PRIMARY : GDK_SELECTION_CLIPBOARD);
if (clipboard != NULL)
{
gchar *text = gtk_clipboard_wait_for_text(clipboard);

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "1418"
#define ZD_SVN_REVISION_NUMBER 1418
#define ZD_SVN_REVISION_STRING "1424M"
#define ZD_SVN_REVISION_NUMBER 1424

View file

@ -78,7 +78,7 @@ PSymbolTable GlobalSymbols;
// Starts a new actor definition
//
//==========================================================================
FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native)
FActorInfo *CreateNewActor(FScriptPosition &sc, FName typeName, FName parentName, bool native)
{
const PClass *replacee = NULL;
PClass *ti = NULL;
@ -89,18 +89,32 @@ FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native)
if (parentName != NAME_None)
{
parent = const_cast<PClass *> (PClass::FindClass (parentName));
const PClass *p = parent;
while (p != NULL)
{
if (p->TypeName == typeName)
{
sc.Message(MSG_ERROR, "'%s' inherits from a class with the same name", typeName.GetChars());
break;
}
p = p->ParentClass;
}
if (parent == NULL)
{
I_Error( "Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
sc.Message(MSG_ERROR, "Parent type '%s' not found in %s", parentName.GetChars(), typeName.GetChars());
parent = RUNTIME_CLASS(AActor);
}
else if (!parent->IsDescendantOf(RUNTIME_CLASS(AActor)))
{
I_Error( "Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
sc.Message(MSG_ERROR, "Parent type '%s' is not an actor in %s", parentName.GetChars(), typeName.GetChars());
parent = RUNTIME_CLASS(AActor);
}
else if (parent->ActorInfo == NULL)
{
I_Error( "uninitialized parent type '%s' in %s", parentName.GetChars(), typeName.GetChars());
sc.Message(MSG_ERROR, "uninitialized parent type '%s' in %s", parentName.GetChars(), typeName.GetChars());
parent = RUNTIME_CLASS(AActor);
}
}
@ -109,21 +123,26 @@ FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native)
ti = (PClass*)PClass::FindClass(typeName);
if (ti == NULL)
{
I_Error( "Unknown native class '%s'", typeName.GetChars());
sc.Message(MSG_ERROR, "Unknown native class '%s'", typeName.GetChars());
goto create;
}
else if (ti != RUNTIME_CLASS(AActor) && ti->ParentClass->NativeClass() != parent->NativeClass())
{
I_Error( "Native class '%s' does not inherit from '%s'", typeName.GetChars(), parentName.GetChars());
sc.Message(MSG_ERROR, "Native class '%s' does not inherit from '%s'", typeName.GetChars(), parentName.GetChars());
parent = RUNTIME_CLASS(AActor);
goto create;
}
else if (ti->ActorInfo != NULL)
{
I_Error( "Redefinition of internal class '%s'", typeName.GetChars());
sc.Message(MSG_ERROR, "Redefinition of internal class '%s'", typeName.GetChars());
goto create;
}
ti->InitializeActorInfo();
info = ti->ActorInfo;
}
else
{
create:
ti = parent->CreateDerivedClass (typeName, parent->Size);
info = ti->ActorInfo;
}

View file

@ -189,7 +189,7 @@ PSymbolActionFunction *FindGlobalActionFunction(const char *name);
//
//==========================================================================
FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native);
FActorInfo *CreateNewActor(FScriptPosition &sc, FName typeName, FName parentName, bool native);
void SetReplacement(FActorInfo *info, FName replaceName);
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod);

View file

@ -206,6 +206,7 @@ static FFlagDef ActorFlags[]=
DEFINE_FLAG(MF5, SUMMONEDMONSTER, AActor, flags5),
DEFINE_FLAG(MF5, NOVERTICALMELEERANGE, AActor, flags5),
DEFINE_FLAG(MF5, BRIGHT, AActor, flags5),
DEFINE_FLAG(MF5, CANTSEEK, AActor, flags5),
// Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View file

@ -704,13 +704,18 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
}
else
{
sc.ScriptError("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), prop->cls->TypeName.GetChars());
sc.ScriptMessage("\"%s\" requires an actor of type \"%s\"\n", propname.GetChars(), prop->cls->TypeName.GetChars());
FScriptPosition::ErrorCounter++;
}
}
else if (!propname.CompareNoCase("States"))
{
if (!bag.StateSet) ParseStates(sc, bag.Info, (AActor *)bag.Info->Class->Defaults, bag);
else sc.ScriptError("Multiple state declarations not allowed");
if (bag.StateSet)
{
sc.ScriptMessage("'%s' contains multiple state declarations", bag.Info->Class->TypeName.GetChars());
FScriptPosition::ErrorCounter++;
}
ParseStates(sc, bag.Info, (AActor *)bag.Info->Class->Defaults, bag);
bag.StateSet=true;
}
else if (MatchString(propname, statenames) != -1)
@ -740,6 +745,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
OPTIONAL = 1
};
bool error = false;
AFuncDesc *afd;
FName funcname;
FString args;
@ -748,7 +754,8 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0)
{
sc.ScriptError ("action functions can only be imported by internal class and actor definitions!");
sc.ScriptMessage ("action functions can only be imported by internal class and actor definitions!");
error++;
}
sc.MustGetToken(TK_Native);
@ -757,7 +764,8 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
afd = FindFunction(sc.String);
if (afd == NULL)
{
sc.ScriptError ("The function '%s' has not been exported from the executable.", sc.String);
sc.ScriptMessage ("The function '%s' has not been exported from the executable.", sc.String);
error++;
}
sc.MustGetToken('(');
if (!sc.CheckToken(')'))
@ -808,7 +816,9 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
sc.UnGet();
break;
default:
sc.ScriptError ("Unknown variable type %s", sc.TokenName(sc.TokenType, sc.String).GetChars());
sc.ScriptMessage ("Unknown variable type %s", sc.TokenName(sc.TokenType, sc.String).GetChars());
type = 'x';
FScriptPosition::ErrorCounter++;
break;
}
// Read the optional variable name
@ -862,11 +872,16 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
{
sym->defaultparameterindex = -1;
}
if (cls->Symbols.AddSymbol (sym) == NULL)
if (error)
{
FScriptPosition::ErrorCounter++;
}
else if (cls->Symbols.AddSymbol (sym) == NULL)
{
delete sym;
sc.ScriptError ("'%s' is already defined in class '%s'.",
sc.ScriptMessage ("'%s' is already defined in class '%s'.",
funcname.GetChars(), cls->TypeName.GetChars());
FScriptPosition::ErrorCounter++;
}
}
@ -935,7 +950,12 @@ static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag)
if (sc.CheckNumber())
{
if (sc.Number>=-1 && sc.Number<32768) DoomEdNum = sc.Number;
else sc.ScriptError ("DoomEdNum must be in the range [-1,32767]");
else
{
// does not need to be fatal.
sc.ScriptMessage ("DoomEdNum must be in the range [-1,32767]");
FScriptPosition::ErrorCounter++;
}
}
if (sc.CheckString("native"))
@ -945,7 +965,7 @@ static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag)
try
{
FActorInfo *info = CreateNewActor(typeName, parentName, native);
FActorInfo *info = CreateNewActor(FScriptPosition(sc), typeName, parentName, native);
info->DoomEdNum = DoomEdNum > 0? DoomEdNum : -1;
SetReplacement(info, replaceName);

View file

@ -2104,7 +2104,6 @@ EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int bol
void V_InitFonts()
{
V_InitFontColors ();
V_InitCustomFonts ();
// load the heads-up font

View file

@ -134,5 +134,6 @@ EColorRange V_FindFontColor (FName name);
PalEntry V_LogColorFromColorRange (EColorRange range);
EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor);
FFont *V_GetFont(const char *);
void V_InitFontColors();
#endif //__V_FONT_H__

View file

@ -1807,25 +1807,18 @@ void WI_drawStats (void)
screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 90, "ITEMS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
screen->DrawText (BigFont, CR_UNTRANSLATED, 50, 115, "SECRETS", DTA_Clean, true, DTA_Shadow, true, TAG_DONE);
int slashpos = gameinfo.gametype==GAME_Strife? 235:237;
int countpos = gameinfo.gametype==GAME_Strife? 185:200;
int countpos = gameinfo.gametype==GAME_Strife? 285:270;
if (sp_state >= 2)
{
WI_drawNum (IntermissionFont, countpos, 65, cnt_kills[0], 3, false);
WI_DrawCharPatch (IntermissionFont, '/', slashpos, 65);
WI_drawNum (IntermissionFont, 248, 65, wbs->maxkills, 3, false);
WI_drawPercent (IntermissionFont, countpos, 65, cnt_kills[0], wbs->maxkills);
}
if (sp_state >= 4)
{
WI_drawNum (IntermissionFont, countpos, 90, cnt_items[0], 3, false);
WI_DrawCharPatch (IntermissionFont, '/', slashpos, 90);
WI_drawNum (IntermissionFont, 248, 90, wbs->maxitems, 3, false);
WI_drawPercent (IntermissionFont, countpos, 90, cnt_items[0], wbs->maxitems);
}
if (sp_state >= 6)
{
WI_drawNum (IntermissionFont, countpos, 115, cnt_secret[0], 3, false);
WI_DrawCharPatch (IntermissionFont, '/', slashpos, 115);
WI_drawNum (IntermissionFont, 248, 115, wbs->maxsecret, 3, false);
WI_drawPercent (IntermissionFont, countpos, 115, cnt_secret[0], wbs->maxsecret);
}
if (sp_state >= 8)
{

View file

@ -97,6 +97,7 @@
#include "templates.h"
#include "cmdlib.h"
#include "d_event.h"
#include "v_text.h"
#define DINPUT_BUFFERSIZE 32
@ -2041,14 +2042,14 @@ void I_PutInClipboard (const char *str)
CloseClipboard ();
}
FString I_GetFromClipboard ()
FString I_GetFromClipboard (bool return_nothing)
{
FString retstr;
HGLOBAL cliphandle;
char *clipstr;
char *nlstr;
if (!IsClipboardFormatAvailable (CF_TEXT) || !OpenClipboard (Window))
if (return_nothing || !IsClipboardFormatAvailable (CF_TEXT) || !OpenClipboard (Window))
return retstr;
cliphandle = GetClipboardData (CF_TEXT);

View file

@ -39,7 +39,7 @@
bool I_InitInput (void *hwnd);
void I_ShutdownInput ();
void I_PutInClipboard (const char *str);
FString I_GetFromClipboard ();
FString I_GetFromClipboard (bool windows_has_no_selection_clipboard);
void I_GetEvent ();

View file

@ -743,7 +743,7 @@ void ShowErrorPane(const char *text)
SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end);
ErrorIconChar = end.cpMax;
// Now start adding the actualy error message.
// Now start adding the actual error message.
SendMessage (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"Execution could not continue.\n\n");
// Restore old charformat but with light yellow text.