- 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.

SVN r1425 (trunk)
This commit is contained in:
Christoph Oelckers 2009-02-19 14:36:37 +00:00
parent 0acc6a4ee3
commit 666e40c8bb
23 changed files with 545 additions and 416 deletions

View File

@ -1,3 +1,27 @@
February 15, 2009 (Changes by Graf Zahl)
- Fixed: The CHARFORMAT structure that is used to set the color in a Windows
Rich Edit control was not fully initialized resulting in incorrect colors
being set.
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 February 10, 2009
- Moved the V_InitFontColors() call earlier in the startup sequence so that - Moved the V_InitFontColors() call earlier in the startup sequence so that
colored error messages appear colored in the startup window. Also lightened colored error messages appear colored in the startup window. Also lightened

View File

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

View File

@ -798,7 +798,9 @@ void AM_loadPics ()
marknums[i] = TexMan.CheckForTexture (namebuf, FTexture::TEX_MiscPatch); 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 () bool AM_clearMarks ()

View File

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

View File

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

View File

@ -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 // ParseLookupname
@ -715,6 +730,7 @@ void FMapInfoParser::ParseCluster()
break; break;
} }
} }
CheckEndOfFile("cluster");
} }
@ -1191,6 +1207,13 @@ DEFINE_MAP_OPTION(teamdamage, true)
info->teamdamage = parse.sc.Float; info->teamdamage = parse.sc.Float;
} }
DEFINE_MAP_OPTION(mapbackground, true)
{
parse.ParseAssign();
parse.ParseLumpOrTextureName(info->mapbg);
}
//========================================================================== //==========================================================================
// //
// All flag based map options // 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; break;
} }
} }
CheckEndOfFile("episode");
if (extended && !(gameinfo.flags & GI_MENUHACK_EXTENDED)) if (extended && !(gameinfo.flags & GI_MENUHACK_EXTENDED))
{ // If the episode is for the extended Heretic, but this is { // If the episode is for the extended Heretic, but this is

View File

@ -540,6 +540,22 @@ PalEntry APowerStrength::GetBlend ()
IMPLEMENT_CLASS (APowerInvisibility) 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 // APowerInvisibility :: InitEffect
@ -548,11 +564,16 @@ IMPLEMENT_CLASS (APowerInvisibility)
void APowerInvisibility::InitEffect () void APowerInvisibility::InitEffect ()
{ {
Owner->flags |= MF_SHADOW; CommonInit();
Owner->alpha = FRACUNIT/5; Owner->alpha = FRACUNIT/5;
Owner->RenderStyle = STYLE_OptFuzzy; Owner->RenderStyle = STYLE_OptFuzzy;
} }
//===========================================================================
//
// APowerInvisibility :: DoEffect
//
//===========================================================================
void APowerInvisibility::DoEffect () void APowerInvisibility::DoEffect ()
{ {
Super::DoEffect(); Super::DoEffect();
@ -571,6 +592,7 @@ void APowerInvisibility::EndEffect ()
{ {
if (Owner != NULL) if (Owner != NULL)
{ {
if (flags5 & MF5_CANTSEEK) Owner->flags5 &= ~MF5_CANTSEEK;
Owner->flags &= ~MF_SHADOW; Owner->flags &= ~MF_SHADOW;
Owner->flags3 &= ~MF3_GHOST; Owner->flags3 &= ~MF3_GHOST;
Owner->RenderStyle = STYLE_Normal; Owner->RenderStyle = STYLE_Normal;
@ -628,7 +650,7 @@ IMPLEMENT_CLASS (APowerGhost)
void APowerGhost::InitEffect () void APowerGhost::InitEffect ()
{ {
Owner->flags |= MF_SHADOW; CommonInit();
Owner->flags3 |= MF3_GHOST; Owner->flags3 |= MF3_GHOST;
Owner->alpha = HR_SHADOW; Owner->alpha = HR_SHADOW;
Owner->RenderStyle = STYLE_Translucent; Owner->RenderStyle = STYLE_Translucent;
@ -705,7 +727,7 @@ bool APowerShadow::HandlePickup (AInventory *item)
void APowerShadow::InitEffect () void APowerShadow::InitEffect ()
{ {
Owner->flags |= MF_SHADOW; CommonInit();
Owner->alpha = special1 == 0 ? TRANSLUC25 : 0; Owner->alpha = special1 == 0 ? TRANSLUC25 : 0;
Owner->RenderStyle = STYLE_Translucent; Owner->RenderStyle = STYLE_Translucent;
} }

View File

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

View File

@ -309,7 +309,7 @@ void DSBarInfo::Tick ()
oldHealth += clamp((health - oldHealth), 1, script->interpolationSpeed); 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) if(armor == NULL)
{ {
oldArmor = 0; oldArmor = 0;

View File

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

View File

@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Tracer2)
dest = self->tracer; 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; return;
// change angle // change angle

View File

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

View File

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

View File

@ -1221,7 +1221,14 @@ DEFINE_ACTION_FUNCTION(AActor, A_PlayerScream)
if (self->player == NULL || self->DeathSound != 0) 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; return;
} }

View File

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

View File

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

View File

@ -78,7 +78,7 @@ PSymbolTable GlobalSymbols;
// Starts a new actor definition // 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; const PClass *replacee = NULL;
PClass *ti = NULL; PClass *ti = NULL;
@ -89,18 +89,32 @@ FActorInfo *CreateNewActor(FName typeName, FName parentName, bool native)
if (parentName != NAME_None) if (parentName != NAME_None)
{ {
parent = const_cast<PClass *> (PClass::FindClass (parentName)); 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) 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))) 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) 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); ti = (PClass*)PClass::FindClass(typeName);
if (ti == NULL) 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()) 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) 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(); ti->InitializeActorInfo();
info = ti->ActorInfo; info = ti->ActorInfo;
} }
else else
{ {
create:
ti = parent->CreateDerivedClass (typeName, parent->Size); ti = parent->CreateDerivedClass (typeName, parent->Size);
info = ti->ActorInfo; 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 SetReplacement(FActorInfo *info, FName replaceName);
void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod); 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, SUMMONEDMONSTER, AActor, flags5),
DEFINE_FLAG(MF5, NOVERTICALMELEERANGE, AActor, flags5), DEFINE_FLAG(MF5, NOVERTICALMELEERANGE, AActor, flags5),
DEFINE_FLAG(MF5, BRIGHT, AActor, flags5), DEFINE_FLAG(MF5, BRIGHT, AActor, flags5),
DEFINE_FLAG(MF5, CANTSEEK, AActor, flags5),
// Effect flags // Effect flags
DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects),

View File

@ -704,13 +704,18 @@ static void ParseActorProperty(FScanner &sc, Baggage &bag)
} }
else 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")) else if (!propname.CompareNoCase("States"))
{ {
if (!bag.StateSet) ParseStates(sc, bag.Info, (AActor *)bag.Info->Class->Defaults, bag); if (bag.StateSet)
else sc.ScriptError("Multiple state declarations not allowed"); {
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; bag.StateSet=true;
} }
else if (MatchString(propname, statenames) != -1) else if (MatchString(propname, statenames) != -1)
@ -740,6 +745,7 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
OPTIONAL = 1 OPTIONAL = 1
}; };
bool error = false;
AFuncDesc *afd; AFuncDesc *afd;
FName funcname; FName funcname;
FString args; FString args;
@ -748,7 +754,8 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) 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); sc.MustGetToken(TK_Native);
@ -757,7 +764,8 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
afd = FindFunction(sc.String); afd = FindFunction(sc.String);
if (afd == NULL) 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('('); sc.MustGetToken('(');
if (!sc.CheckToken(')')) if (!sc.CheckToken(')'))
@ -808,7 +816,9 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
sc.UnGet(); sc.UnGet();
break; break;
default: 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; break;
} }
// Read the optional variable name // Read the optional variable name
@ -862,11 +872,16 @@ static void ParseActionDef (FScanner &sc, PClass *cls)
{ {
sym->defaultparameterindex = -1; sym->defaultparameterindex = -1;
} }
if (cls->Symbols.AddSymbol (sym) == NULL) if (error)
{
FScriptPosition::ErrorCounter++;
}
else if (cls->Symbols.AddSymbol (sym) == NULL)
{ {
delete sym; 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()); funcname.GetChars(), cls->TypeName.GetChars());
FScriptPosition::ErrorCounter++;
} }
} }
@ -935,7 +950,12 @@ static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag)
if (sc.CheckNumber()) if (sc.CheckNumber())
{ {
if (sc.Number>=-1 && sc.Number<32768) DoomEdNum = sc.Number; 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")) if (sc.CheckString("native"))
@ -945,7 +965,7 @@ static FActorInfo *ParseActorHeader(FScanner &sc, Baggage *bag)
try try
{ {
FActorInfo *info = CreateNewActor(typeName, parentName, native); FActorInfo *info = CreateNewActor(FScriptPosition(sc), typeName, parentName, native);
info->DoomEdNum = DoomEdNum > 0? DoomEdNum : -1; info->DoomEdNum = DoomEdNum > 0? DoomEdNum : -1;
SetReplacement(info, replaceName); SetReplacement(info, replaceName);

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, 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); 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? 285:270;
int countpos = gameinfo.gametype==GAME_Strife? 185:200;
if (sp_state >= 2) if (sp_state >= 2)
{ {
WI_drawNum (IntermissionFont, countpos, 65, cnt_kills[0], 3, false); WI_drawPercent (IntermissionFont, countpos, 65, cnt_kills[0], wbs->maxkills);
WI_DrawCharPatch (IntermissionFont, '/', slashpos, 65);
WI_drawNum (IntermissionFont, 248, 65, wbs->maxkills, 3, false);
} }
if (sp_state >= 4) if (sp_state >= 4)
{ {
WI_drawNum (IntermissionFont, countpos, 90, cnt_items[0], 3, false); WI_drawPercent (IntermissionFont, countpos, 90, cnt_items[0], wbs->maxitems);
WI_DrawCharPatch (IntermissionFont, '/', slashpos, 90);
WI_drawNum (IntermissionFont, 248, 90, wbs->maxitems, 3, false);
} }
if (sp_state >= 6) if (sp_state >= 6)
{ {
WI_drawNum (IntermissionFont, countpos, 115, cnt_secret[0], 3, false); WI_drawPercent (IntermissionFont, countpos, 115, cnt_secret[0], wbs->maxsecret);
WI_DrawCharPatch (IntermissionFont, '/', slashpos, 115);
WI_drawNum (IntermissionFont, 248, 115, wbs->maxsecret, 3, false);
} }
if (sp_state >= 8) if (sp_state >= 8)
{ {

View File

@ -566,6 +566,7 @@ void I_PrintStr (const char *cp)
// Change the color. // Change the color.
format.cbSize = sizeof(format); format.cbSize = sizeof(format);
format.dwMask = CFM_COLOR; format.dwMask = CFM_COLOR;
format.dwEffects = 0;
format.crTextColor = color; format.crTextColor = color;
SendMessage (edit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format); SendMessage (edit, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&format);
} }

File diff suppressed because it is too large Load Diff