diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 3f5ffd4ab0..d91063b7ac 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,16 @@ +July 3, 2006 (Changes by Graf Zahl) +- Fixed: Changed initialization of Weapon.Kickback so that it is only done + for direct descendants of AWeapon and not for every weapon being defined. +- Changed parsing of actor names back to not use C-mode. This change breaks + any definition that contains periods in their name and apparently there's + more than anyone could expect. Also altered the parser to manually check + for colons inside the parsed string so that placing spaces around them + is no longer necessary. +- Fixed: Weapons could be picked up for ammo even if they gave none. +- Fixed: A_Beacon was missing a NULL pointer check for the beacon's owner. +- Fixed: The status bar tried to access CPlayer->camera without checking + its validity. In spy mode there is a possibility that it is NULL. + July 2, 2006 (Changes by Graf Zahl) - Fixed: G_NewInit destroyed the players' userinfo data. - Changed the special radius damage handling for the barrel and boss brain diff --git a/src/g_hexen/a_clericplayer.cpp b/src/g_hexen/a_clericplayer.cpp index e0b22e06dd..19166452d9 100644 --- a/src/g_hexen/a_clericplayer.cpp +++ b/src/g_hexen/a_clericplayer.cpp @@ -186,7 +186,9 @@ void AClericPlayer::SpecialInvulnerabilityHandling (EInvulState state, fixed_t * // Cleric Weapon Base Class ------------------------------------------------- -IMPLEMENT_ABSTRACT_ACTOR (AClericWeapon) +IMPLEMENT_STATELESS_ACTOR (AClericWeapon, Hexen, -1, 0) + PROP_Weapon_Kickback (150) +END_DEFAULTS bool AClericWeapon::TryPickup (AActor *toucher) { diff --git a/src/g_hexen/a_fighterplayer.cpp b/src/g_hexen/a_fighterplayer.cpp index 846af55717..1ca8975df4 100644 --- a/src/g_hexen/a_fighterplayer.cpp +++ b/src/g_hexen/a_fighterplayer.cpp @@ -395,7 +395,9 @@ bool AFighterPlayer::DoHealingRadius (APlayerPawn *other) // Fighter Weapon Base Class ------------------------------------------------ -IMPLEMENT_ABSTRACT_ACTOR (AFighterWeapon) +IMPLEMENT_STATELESS_ACTOR (AFighterWeapon, Hexen, -1, 0) + PROP_Weapon_Kickback (150) +END_DEFAULTS bool AFighterWeapon::TryPickup (AActor *toucher) { diff --git a/src/g_hexen/a_mageplayer.cpp b/src/g_hexen/a_mageplayer.cpp index 8d69c8af76..b68a7c4131 100644 --- a/src/g_hexen/a_mageplayer.cpp +++ b/src/g_hexen/a_mageplayer.cpp @@ -192,7 +192,9 @@ void AMagePlayer::SpecialInvulnerabilityHandling (EInvulState state, fixed_t * p // Mage Weapon Base Class --------------------------------------------------- -IMPLEMENT_ABSTRACT_ACTOR (AMageWeapon) +IMPLEMENT_STATELESS_ACTOR (AMageWeapon, Hexen, -1, 0) + PROP_Weapon_Kickback (150) +END_DEFAULTS bool AMageWeapon::TryPickup (AActor *toucher) { diff --git a/src/g_shared/a_weapons.cpp b/src/g_shared/a_weapons.cpp index 18607cffd3..4b8147ba14 100644 --- a/src/g_shared/a_weapons.cpp +++ b/src/g_shared/a_weapons.cpp @@ -149,8 +149,8 @@ bool AWeapon::PickupForAmmo (AWeapon *ownedWeapon) // Don't take ammo if the weapon sticks around. if (!ShouldStay ()) { - gotstuff = AddExistingAmmo (ownedWeapon->Ammo1, AmmoGive1); - gotstuff |= AddExistingAmmo (ownedWeapon->Ammo2, AmmoGive2); + if (AmmoGive1 > 0) gotstuff = AddExistingAmmo (ownedWeapon->Ammo1, AmmoGive1); + if (AmmoGive2 > 0) gotstuff |= AddExistingAmmo (ownedWeapon->Ammo2, AmmoGive2); } return gotstuff; } diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index 3c27601cca..b71f3bb1c9 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1115,7 +1115,7 @@ void FBaseStatusBar::Draw (EHudState state) if (viewactive) { - if (CPlayer && CPlayer->camera->player) + if (CPlayer && CPlayer->camera && CPlayer->camera->player) { DrawCrosshair (); } diff --git a/src/g_strife/a_rebels.cpp b/src/g_strife/a_rebels.cpp index 182a876a78..58e312e500 100644 --- a/src/g_strife/a_rebels.cpp +++ b/src/g_strife/a_rebels.cpp @@ -277,7 +277,6 @@ void A_Beacon (AActor *self) { AActor *owner = self->target; ARebel *rebel; - int friendNum; angle_t an; rebel = Spawn (self->x, self->y, ONFLOORZ); @@ -290,8 +289,6 @@ void A_Beacon (AActor *self) self->flags &= ~MF_SPECIAL; static_cast(self)->DropTime = 0; // Set up the new rebel. - friendNum = owner->player != NULL ? int(owner->player - players + 1) : 0; - rebel->FriendPlayer = friendNum; rebel->threshold = 100; rebel->target = NULL; rebel->flags4 |= MF4_INCOMBAT; @@ -304,16 +301,15 @@ void A_Beacon (AActor *self) { // Rebels are the same color as their owner rebel->Translation = owner->Translation; + rebel->FriendPlayer = owner->player != NULL ? int(owner->player - players + 1) : 0; // Set the rebel's target to whatever last hurt the player, so long as it's not // one of the player's other rebels. - if (owner->target != NULL && - (!(owner->target->flags & MF_FRIENDLY) || - owner->target->FriendPlayer == 0 || - owner->target->FriendPlayer != friendNum)) + if (owner->target != NULL && !rebel->IsFriend (owner->target)) { rebel->target = owner->target; } } + rebel->SetState (rebel->SeeState); rebel->angle = self->angle; an = self->angle >> ANGLETOFINESHIFT; diff --git a/src/thingdef.cpp b/src/thingdef.cpp index 53aa1f78ee..05ee9e2ee7 100644 --- a/src/thingdef.cpp +++ b/src/thingdef.cpp @@ -1214,6 +1214,12 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag) FName typeName; SC_MustGetString(); + + char * colon = strchr(sc_String, ':'); + if (colon != NULL) + { + *colon++ = 0; + } if (PClass::FindClass (sc_String) != NULL) { @@ -1226,19 +1232,38 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag) if (parentc) { *parentc = NULL; - SC_MustGetString(); - if (SC_Compare(":")) + + // Do some tweaking so that a definition like 'Actor:Parent' which is read as a single token is recognized as well + // without having resort to C-mode (which disallows periods in actor names.) + if (colon == NULL) { - SC_MustGetString(); - parent = const_cast (PClass::FindClass (sc_String)); + SC_MustGetString (); + if (sc_String[0]==':') + { + colon = sc_String + 1; + } + } + + if (colon != NULL) + { + if (colon[0] == 0) + { + SC_MustGetString (); + colon = sc_String; + } + } + + if (colon != NULL) + { + parent = const_cast (PClass::FindClass (colon)); if (parent == NULL) { - SC_ScriptError ("Parent type '%s' not found", sc_String); + SC_ScriptError ("Parent type '%s' not found", colon); } else if (parent->ActorInfo == NULL) { - SC_ScriptError ("Parent type '%s' is not an actor", sc_String); + SC_ScriptError ("Parent type '%s' is not an actor", colon); } else { @@ -1260,12 +1285,16 @@ static FActorInfo * CreateNewActor(FActorInfo ** parentc, Baggage *bag) bag->Info = info; info->DoomEdNum=-1; + + // Now, after the actor names have been parsed, it is time to switch to C-mode + // for the rest of the actor definition. + SC_SetCMode (true); if (SC_CheckNumber()) { - if (sc_Number>=-1 && sc_Number<32768) info->DoomEdNum=sc_Number; + if (sc_Number>=-1 && sc_Number<32768) info->DoomEdNum = sc_Number; else SC_ScriptError ("DoomEdNum must be in the range [-1,32767]"); } - if (ti->IsDescendantOf(RUNTIME_CLASS(AWeapon))) + if (parent == RUNTIME_CLASS(AWeapon)) { // preinitialize kickback to the default for the game ((AWeapon*)(info->Class->Defaults))->Kickback=gameinfo.defKickback; @@ -2148,7 +2177,6 @@ void ProcessActor(void (*process)(FState *, int)) { FActorInfo * parent; - SC_SetCMode (true); info=CreateNewActor(&parent, &bag); defaults=(AActor*)info->Class->Defaults;