From 42ac64d96455e64001873bbef1c6e7f5f95f595c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 28 Feb 2009 21:38:20 +0000 Subject: [PATCH] - Fixed: Strife's quest based line actions also work in Deathmatch. - Fixed: Gravity application was not correct. For actors with no vertical momentum the initial pull is supposed to be twice as strong as when vertical movement already takes place. - added invquery CCMD like in Strife. Also removed all underscores from the tag strings so that they can be printed properly. - Fixed: Skill baby was missing 'autousehealth' for all games. - Added a new CVAR: sv_disableautohealth - Autouse of health items is no longer hardwired to the default item classes. There's a new property HealthPickup.Autouse. 0 means no autouse, 1 a small Raven health item, 2 a large Raven health item and 3 a Strife item. SVN r1452 (trunk) --- docs/rh-log.txt | 15 +- src/c_bind.cpp | 2 +- src/g_game.cpp | 11 ++ src/g_shared/a_pickups.cpp | 12 ++ src/g_shared/a_pickups.h | 3 + src/m_options.cpp | 1 + src/p_interaction.cpp | 172 +++++++++++------- src/p_mobj.cpp | 7 +- src/thingdef/thingdef_properties.cpp | 9 + src/version.h | 2 +- strifehelp.acs | 19 +- wadsrc/static/acs/strfhelp.o | Bin 3124 -> 3176 bytes wadsrc/static/actors/raven/ravenartifacts.txt | 2 + wadsrc/static/actors/strife/coin.txt | 8 +- wadsrc/static/actors/strife/merchants.txt | 4 +- wadsrc/static/actors/strife/ratbuddy.txt | 2 +- wadsrc/static/actors/strife/rebels.txt | 2 +- wadsrc/static/actors/strife/strifeammo.txt | 22 +-- wadsrc/static/actors/strife/strifearmor.txt | 4 +- wadsrc/static/actors/strife/strifeitems.txt | 38 ++-- wadsrc/static/actors/strife/strifekeys.txt | 52 +++--- wadsrc/static/actors/strife/strifeweapons.txt | 12 +- wadsrc/static/mapinfo/chex.txt | 1 + wadsrc/static/mapinfo/doomcommon.txt | 1 + wadsrc/static/mapinfo/heretic.txt | 1 + wadsrc/static/mapinfo/hexen.txt | 1 + wadsrc/static/mapinfo/strife.txt | 1 + 27 files changed, 254 insertions(+), 150 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index d8c9ec555..fd64569a7 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,17 @@ -February 26, 2009 +February 28, 2009 (Changes by Graf Zahl) +- Fixed: Strife's quest based line actions also work in Deathmatch. +- Fixed: Gravity application was not correct. For actors with no vertical + momentum the initial pull is supposed to be twice as strong as when + vertical movement already takes place. +- added invquery CCMD like in Strife. Also removed all underscores from the + tag strings so that they can be printed properly. +- Fixed: Skill baby was missing 'autousehealth' for all games. +- Added a new CVAR: sv_disableautohealth +- Autouse of health items is no longer hardwired to the default item classes. + There's a new property HealthPickup.Autouse. 0 means no autouse, 1 a small + Raven health item, 2 a large Raven health item and 3 a Strife item. + +February 26, 2009 - Removed an early-out in wallscan_striped() that is invalid when drawing a skybox. diff --git a/src/c_bind.cpp b/src/c_bind.cpp index 422437d3c..a6d8488ea 100644 --- a/src/c_bind.cpp +++ b/src/c_bind.cpp @@ -153,10 +153,10 @@ static const FBinding DefStrifeBindings[] = { "backspace", "invdrop" }, { "z", "showpop 3" }, { "k", "showpop 2" }, + { "q", "invquery" }, { NULL } // not done // h - use health - // q - query inventory }; const char *KeyNames[NUM_KEYS] = diff --git a/src/g_game.cpp b/src/g_game.cpp index f2fc66875..343184b4d 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -374,6 +374,17 @@ CCMD (invuse) players[consoleplayer].inventorytics = 0; } +CCMD(invquery) +{ + AInventory *inv = players[consoleplayer].mo->InvSel; + if (inv != NULL) + { + const char *description = inv->GetClass()->Meta.GetMetaString(AMETA_StrifeName); + if (description == NULL) description = inv->GetClass()->TypeName; + Printf(PRINT_HIGH, "%s (%dx)\n", description, inv->Amount); + } +} + CCMD (use) { if (argv.argc() > 1 && who != NULL) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index a9689f4af..c23799806 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1530,6 +1530,18 @@ bool AHealthPickup::Use (bool pickup) return P_GiveBody (Owner, health); } +//=========================================================================== +// +// AHealthPickup :: Serialize +// +//=========================================================================== + +void AHealthPickup::Serialize (FArchive &arc) +{ + Super::Serialize(arc); + arc << autousemode; +} + // Backpack ----------------------------------------------------------------- //=========================================================================== diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index d95e04dd1..dd6067b74 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -341,6 +341,9 @@ class AHealthPickup : public AInventory { DECLARE_CLASS (AHealthPickup, AInventory) public: + int autousemode; + + virtual void Serialize (FArchive &arc); virtual AInventory *CreateCopy (AActor *other); virtual AInventory *CreateTossable (); virtual bool HandlePickup (AInventory *item); diff --git a/src/m_options.cpp b/src/m_options.cpp index 8ed8c6b42..72fb5a8b1 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -425,6 +425,7 @@ static menuitem_t ControlsItems[] = { control, "Next item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invnext"} }, { control, "Previous item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invprev"} }, { control, "Drop item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invdrop"} }, + { control, "Query item", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"invquery"} }, { control, "Drop weapon", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)"weapdrop"} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { whitetext,"Other", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 9a5c7a4f3..876d5c5f1 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -719,72 +719,89 @@ void AActor::Die (AActor *source, AActor *inflictor) // PROC P_AutoUseHealth // //--------------------------------------------------------------------------- +static int CountHealth(TArray &Items) +{ + int counted = 0; + for(unsigned i = 0; i < Items.Size(); i++) + { + counted += Items[i]->Amount * Items[i]->health; + } + return counted; +} + +static int UseHealthItems(TArray &Items, int &saveHealth) +{ + int saved = 0; + + while (Items.Size() > 0 && saveHealth > 0) + { + int maxhealth = 0; + int index = -1; + + // Find the largest item in the list + for(unsigned i = 0; i < Items.Size(); i++) + { + if (Items[i]->health > maxhealth) + { + index = i; + maxhealth = Items[i]->Amount; + } + } + + // Now apply the health items, using the same logic as Heretic anf Hexen. + int count = (saveHealth + maxhealth-1) / maxhealth; + for(int i = 0; i < count; i++) + { + saved += maxhealth; + saveHealth -= maxhealth; + if (--Items[index]->Amount == 0) + { + if (!(Items[index]->ItemFlags & IF_KEEPDEPLETED)) + { + Items[index]->Destroy (); + } + Items.Delete(index); + break; + } + } + } + return saved; +} void P_AutoUseHealth(player_t *player, int saveHealth) { - int i; - int count; - const PClass *normalType = PClass::FindClass (NAME_ArtiHealth); - const PClass *superType = PClass::FindClass (NAME_ArtiSuperHealth); - AInventory *normalItem = player->mo->FindInventory (normalType); - AInventory *superItem = player->mo->FindInventory (superType); - int normalAmount, superAmount; + TArray NormalHealthItems; + TArray LargeHealthItems; - normalAmount = normalItem != NULL ? normalItem->Amount : 0; - superAmount = superItem != NULL ? superItem->Amount : 0; + for(AInventory *inv = player->mo->Inventory; inv != NULL; inv = inv->Inventory) + { + if (inv->Amount > 0 && inv->IsKindOf(RUNTIME_CLASS(AHealthPickup))) + { + int mode = static_cast(inv)->autousemode; + + if (mode == 0) NormalHealthItems.Push(inv); + else if (mode == 1) LargeHealthItems.Push(inv); + } + } + + int normalhealth = CountHealth(NormalHealthItems); + int largehealth = CountHealth(LargeHealthItems); bool skilluse = !!G_SkillProperty(SKILLP_AutoUseHealth); - if (skilluse && (normalAmount*25 >= saveHealth)) + if (skilluse && normalhealth >= saveHealth) { // Use quartz flasks - count = (saveHealth+24)/25; - for(i = 0; i < count; i++) - { - player->health += 25; - if (--normalItem->Amount == 0) - { - normalItem->Destroy (); - break; - } - } + player->health += UseHealthItems(NormalHealthItems, saveHealth); } - else if (superAmount*100 >= saveHealth) - { // Use mystic urns - count = (saveHealth+99)/100; - for(i = 0; i < count; i++) - { - player->health += 100; - if (--superItem->Amount == 0) - { - superItem->Destroy (); - break; - } - } + else if (largehealth >= saveHealth) + { + // Use mystic urns + player->health += UseHealthItems(LargeHealthItems, saveHealth); } - else if (skilluse - && (superAmount*100+normalAmount*25 >= saveHealth)) + else if (skilluse && normalhealth + largehealth >= saveHealth) { // Use mystic urns and quartz flasks - count = (saveHealth+24)/25; - saveHealth -= count*25; - for(i = 0; i < count; i++) - { - player->health += 25; - if (--normalItem->Amount == 0) - { - normalItem->Destroy (); - break; - } - } - count = (saveHealth+99)/100; - for(i = 0; i < count; i++) - { - player->health += 100; - if (--superItem->Amount == 0) - { - superItem->Destroy (); - break; - } - } + player->health += UseHealthItems(NormalHealthItems, saveHealth); + if (saveHealth > 0) player->health += UseHealthItems(LargeHealthItems, saveHealth); } player->mo->health = player->health; } @@ -794,22 +811,47 @@ void P_AutoUseHealth(player_t *player, int saveHealth) // P_AutoUseStrifeHealth // //============================================================================ +CVAR(Bool, sv_disableautohealth, false, CVAR_ARCHIVE|CVAR_SERVERINFO) void P_AutoUseStrifeHealth (player_t *player) { - static const ENamedName healthnames[2] = { NAME_MedicalKit, NAME_MedPatch }; + TArray Items; - for (int i = 0; i < 2; ++i) + for(AInventory *inv = player->mo->Inventory; inv != NULL; inv = inv->Inventory) { - const PClass *type = PClass::FindClass (healthnames[i]); - - while (player->health < 50) + if (inv->Amount > 0 && inv->IsKindOf(RUNTIME_CLASS(AHealthPickup))) { - AInventory *item = player->mo->FindInventory (type); - if (item == NULL) - break; - if (!player->mo->UseInventory (item)) - break; + int mode = static_cast(inv)->autousemode; + + if (mode == 3) Items.Push(inv); + } + } + + if (!sv_disableautohealth) + { + while (Items.Size() > 0) + { + int maxhealth = 0; + int index = -1; + + // Find the largest item in the list + for(unsigned i = 0; i < Items.Size(); i++) + { + if (Items[i]->health > maxhealth) + { + index = i; + maxhealth = Items[i]->Amount; + } + } + + while (player->health < 50) + { + if (!player->mo->UseInventory (Items[index])) + break; + } + if (player->health >= 50) return; + // Using all of this item was not enough so delete it and restart with the next best one + Items.Delete(index); } } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 3b1e93f5c..6d33313df 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -700,7 +700,7 @@ bool AActor::UseInventory (AInventory *item) return false; } // Don't use it if you don't actually have any of it. - if (item->Amount <= 0) + if (item->Amount <= 0 || (item->ObjectFlags & OF_EuthanizeMe)) { return false; } @@ -1876,8 +1876,11 @@ void P_ZMovement (AActor *mo) if (!mo->waterlevel || mo->flags & MF_CORPSE || (mo->player && !(mo->player->cmd.ucmd.forwardmove | mo->player->cmd.ucmd.sidemove))) { - mo->momz -= (fixed_t)(level.gravity * mo->Sector->gravity * + fixed_t grav = (fixed_t)(level.gravity * mo->Sector->gravity * FIXED2FLOAT(mo->gravity) * 81.92); + + if (mo->momz == 0) mo->momz -= grav + grav; + else mo->momz -= grav; } if (mo->waterlevel > 1) { diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 67233b391..f08e5ed9b 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1244,6 +1244,15 @@ DEFINE_CLASS_PROPERTY(lowmessage, IS, Health) info->Class->Meta.SetMetaString(AIMETA_LowHealthMessage, str); } +//========================================================================== +// +//========================================================================== +DEFINE_CLASS_PROPERTY(autouse, I, HealthPickup) +{ + PROP_INT_PARM(i, 0); + defaults->autousemode = i; +} + //========================================================================== // //========================================================================== diff --git a/src/version.h b/src/version.h index ea6ff1034..2c4729ffc 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 1447 +#define MINSAVEVER 1452 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need diff --git a/strifehelp.acs b/strifehelp.acs index a6a3d4fcc..382af54b3 100644 --- a/strifehelp.acs +++ b/strifehelp.acs @@ -69,7 +69,7 @@ script << 0 >> (int type, int tag) case 230: i = GetLineRowOffset() & 31; - if (CheckInventory (QuestItems[i])) + if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Door_Open (tag, VDOORSPEED); clearlinespecial (); @@ -78,7 +78,7 @@ script << 0 >> (int type, int tag) case 227: i = GetLineRowOffset() & 31; - if (CheckInventory (QuestItems[i])) + if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Door_Close (tag, VDOORSPEED); clearlinespecial (); @@ -126,7 +126,7 @@ script << 0 >> (int type, int tag) case 193: i = GetLineRowOffset() & 31; - if (CheckInventory (QuestItems[i])) + if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Floor_LowerToLowest (tag, 8); clearlinespecial (); @@ -147,7 +147,7 @@ script << 0 >> (int type, int tag) case 187: i = GetLineRowOffset() & 31; - if (CheckInventory (QuestItems[i])) + if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { ClearForceField (tag); clearlinespecial (); @@ -155,7 +155,7 @@ script << 0 >> (int type, int tag) break; case 188: - if (CheckInventory ("QuestItem16")) + if (CheckInventory ("QuestItem16") || gametype() == GAME_NET_DEATHMATCH) { Door_Open (tag, VDOORSPEED); clearlinespecial (); @@ -172,7 +172,7 @@ script << 0 >> (int type, int tag) case 215: i = (tag % 100) & 31; - if (CheckInventory (QuestItems[i])) + if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { SendToCommunicator (tag/100, 0, 1, 0); clearlinespecial (); @@ -192,7 +192,7 @@ script << 0 >> (int type, int tag) case 216: i = GetLineRowOffset() & 31; - if (CheckInventory (QuestItems[i])) + if (CheckInventory (QuestItems[i]) || gametype() == GAME_NET_DEATHMATCH) { Door_Raise (tag, VDOORSPEED, VDOORWAIT); } @@ -205,6 +205,7 @@ script << 0 >> (int type, int tag) if (gametype() == GAME_NET_DEATHMATCH) { Floor_RaiseByValue (tag, 128, 64); + clearlinespecial(); } else { @@ -261,7 +262,7 @@ script << 0 >> (int type, int tag) break; case 232: - if (!CheckInventory ("QuestItem18")) + if (!CheckInventory ("QuestItem18") && gametype() != GAME_NET_DEATHMATCH) { print (s:"You need the Oracle Pass!"); activatorsound ("*usefail", 127); @@ -382,7 +383,7 @@ script << 0 >> (int type, int tag) break; case 234: - if (CheckInventory ("QuestItem3")) + if (CheckInventory ("QuestItem3") || gametype() == GAME_NET_DEATHMATCH) { SetResultValue (Door_Raise (tag, VDOORSPEED, VDOORWAIT)); } diff --git a/wadsrc/static/acs/strfhelp.o b/wadsrc/static/acs/strfhelp.o index 820fcb0c716df5384422fb03931620ca858068ba..d267516a7af6d1b9bf1b9d422cf49f96fc7148a6 100644 GIT binary patch delta 1526 zcmZ`(TS!zv7@o5?#am}xbyr!ii-Dj-#v!x9G;<3DCs;H>h@j2#t(UGO$LAoVmIQt2 zp<*h^)=OAvbRjLww4fWn13;%vI-~Y{jnVBP`)7YduRT>f(wNOCbVAlphBvf*2g3 zL8&41L)tMKZla+bDj;+vho809C%dy}X|Pu$8&h4XJ07baDrkWD z_+NMgb4_bAR&2&Rdd)IT@R)QfG#o(55li_!#{S9`eR zD#S>3GPqE<>HlTNq6%=jrazVcld&o&R=OdSHf=@+BO}s9hB7&Yltp|!_M%=?k}{W+ zV!I(y+C-IHrNKG7NKnsVFq8+0O#dhnACT*JBvu{I(Mqb{vOL|&YBBsG1)i6wUQ{E3 zc4>Y-q*>Wa0mkO~TS#CV^6=@#m@+3b1HzrnrxQcPqA#398O6}{gs?|RUD*Ao$5p6P zsnjB^^6{e(Ag@d2&9L(dXZ#E3u-s}pl|@H*8ALDQHDR6}mxl}yGR!=AzVgqcW1+{S z5JrV*Km&G;VO!`5cVcoCjxJkpix7M_@Gkg1;1EvmwvGM366C%EtN~9?!yxnnKo@Wj zSOB~aq=b)v4`7dB6VN{ao`ww}KRXW_hN*Bo1-h`{8L%7yo&#Heqc)BKOQCxSEC9X& zmO=j-cpdfzwh#PU;0XA4z%bUo2X+D{fQP};OGVi55rdN$d;*rhKEuMWFR(^*_!YPU tHU(=#;BP?c=sWNf{6Bz`nB!q#*D&7*R9NpH_d1VSjI+ffe-K{z`wzm>UDE&n delta 1450 zcmZuxTSyd97(TPJyDqM7qpR*F3u#v|iHNa_U9_wvGdPA=R1dvu8=<}QU{Jvby+jZe z8-~?GJ)M`b^%6$eLs1rHT2dC+%XGC1G!;V7OW%KHbT72<&v(xEfB)^A*_jRxgpJMh z&8#Yqu?W-8x*4+y#e(hgT@lwfOYmh3ydpG@zgeI0WI4CaI&*EO2%8Ch1f+;y5vRo( zQy7QzHd?NwrIRHrloEc*4mW(B;&l45q?4Lk^UUU5hjd9>of4Ltdb<0l6n0H6!BnHjtS7=W6LT3;S19NyM zCt*CwLs5QA3dR+T({1-*q{m;7?xfb`&6D0H!HT#5DR=vYE69gzNk^SGq>sq8h!xm< zD9&txSwWRCjRgc7F5#b{LOst7nMABN6OH`u9B0tI3OeF|D?_&dRCxv!QTnt+cnLz+ zc{Ln%I>;LNUTj;$Msv?@u?hDaM+XIZ9Aq!kx@dkYlm|wZDx`ojGN2X#ZD|n~{~LjL zpUU9E5LW1ilZTqYomwG3pODGwsCvFBlumsTglvHdLg>pS;c}jn(A3CcKh9>(D`?D0 zFq97ott}lwYb9!)^ph^=B?tp!VICDgKf_x`LsOy$> z15RC`V$fFGqjgb7bR+E``jIYaP$JtVLt%8f;+k8;2_Y4%C~__!QTOPLw^@I0~>;A*xv(EzWYFmeE{o& z{vq%v>=EoV%oxVwI|3d9ryzI&T!Q^m-~r&MgJZxT{Lg{(M!f)NDDV<^74`~N1AY>C z4g71`BmNEWByb8?3;wNx?|@AzYh>@Spd grenadetype, int angleofs, state flash); diff --git a/wadsrc/static/mapinfo/chex.txt b/wadsrc/static/mapinfo/chex.txt index 81f21bbfa..cdd9aa712 100644 --- a/wadsrc/static/mapinfo/chex.txt +++ b/wadsrc/static/mapinfo/chex.txt @@ -2,6 +2,7 @@ skill baby { + AutoUseHealth AmmoFactor = 2 DamageFactor = 0.5 EasyBossBrain diff --git a/wadsrc/static/mapinfo/doomcommon.txt b/wadsrc/static/mapinfo/doomcommon.txt index fdc49a736..82cf91115 100644 --- a/wadsrc/static/mapinfo/doomcommon.txt +++ b/wadsrc/static/mapinfo/doomcommon.txt @@ -1,5 +1,6 @@ skill baby { + AutoUseHealth AmmoFactor = 2 DamageFactor = 0.5 EasyBossBrain diff --git a/wadsrc/static/mapinfo/heretic.txt b/wadsrc/static/mapinfo/heretic.txt index 1e0576727..11a2b81af 100644 --- a/wadsrc/static/mapinfo/heretic.txt +++ b/wadsrc/static/mapinfo/heretic.txt @@ -1,6 +1,7 @@ // MAPINFO for Heretic (Shareware and Retail) skill baby { + AutoUseHealth AmmoFactor = 1.5 DoubleAmmoFactor = 1.5 DamageFactor = 0.5 diff --git a/wadsrc/static/mapinfo/hexen.txt b/wadsrc/static/mapinfo/hexen.txt index 3de550021..5760d3fb9 100644 --- a/wadsrc/static/mapinfo/hexen.txt +++ b/wadsrc/static/mapinfo/hexen.txt @@ -2,6 +2,7 @@ // Most of the MAPINFO is still in hexen.wad. skill baby { + AutoUseHealth AmmoFactor = 1.5 DoubleAmmoFactor = 1.5 DamageFactor = 0.5 diff --git a/wadsrc/static/mapinfo/strife.txt b/wadsrc/static/mapinfo/strife.txt index 92a5607c6..3ea9f9441 100644 --- a/wadsrc/static/mapinfo/strife.txt +++ b/wadsrc/static/mapinfo/strife.txt @@ -1,6 +1,7 @@ // MAPINFO for Strife (full version and teaser) skill baby { + AutoUseHealth AmmoFactor = 2 DamageFactor = 0.5 EasyBossBrain