mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-27 22:42:57 +00:00
- Fixed: Player names and chat macros that end with incomplete \c escapes now
have those escapes stripped before printing so that they do not merge with subsequent text. - Moved default weapon slot assignments into the player classes. Weapon.SlotNumber is now used solely for mods that want to add new weapons without completely redoing the player's arsenal. Restored some config-based weapon slot customization, though slots are no longer automatically saved to the config and section names have changed slightly. However, unlike before, config slots are now the definitive word on slot assignments and cannot be overridden by any other files loaded. - Fixed: Several weapons were missing a game filter from their definitions. - Removed storage of weapon slots in the config so that weapon slots can be setup in the weapons themselves. Slots are still configurable, since they need to be for KEYCONF to work; any changes simply won't be saved when you quit. - Removed limit on weapon slot sizes. SVN r1428 (trunk)
This commit is contained in:
parent
491abe3a2c
commit
a7e40b56f6
38 changed files with 824 additions and 391 deletions
|
@ -1,8 +1,22 @@
|
|||
February 15, 2009 (Changes by Graf Zahl)
|
||||
February 17, 2009
|
||||
- Fixed: Player names and chat macros that end with incomplete \c escapes now
|
||||
have those escapes stripped before printing so that they do not merge with
|
||||
subsequent text.
|
||||
|
||||
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.
|
||||
|
||||
Feburary 14, 2009
|
||||
- Moved default weapon slot assignments into the player classes.
|
||||
Weapon.SlotNumber is now used solely for mods that want to add new weapons
|
||||
without completely redoing the player's arsenal. Restored some config-based
|
||||
weapon slot customization, though slots are no longer automatically saved
|
||||
to the config and section names have changed slightly. However, unlike
|
||||
before, config slots are now the definitive word on slot assignments and
|
||||
cannot be overridden by any other files loaded.
|
||||
|
||||
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
|
||||
|
@ -22,6 +36,14 @@ February 14, 2009 (Changes by Graf Zahl)
|
|||
- Fixed: The MAPINFO parser ignored missing terminating braces of the last
|
||||
block in the file.
|
||||
|
||||
February 11, 2009
|
||||
- Fixed: Several weapons were missing a game filter from their definitions.
|
||||
- Removed storage of weapon slots in the config so that weapon slots can
|
||||
be setup in the weapons themselves. Slots are still configurable, since
|
||||
they need to be for KEYCONF to work; any changes simply won't be saved
|
||||
when you quit.
|
||||
- Removed limit on weapon slot sizes.
|
||||
|
||||
February 10, 2009
|
||||
- Fixed: DirectInput8Create() used the wrong calling convention.
|
||||
- Moved the V_InitFontColors() call earlier in the startup sequence so that
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "doomtype.h"
|
||||
#include "cmdlib.h"
|
||||
#include "i_system.h"
|
||||
#include "v_text.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
@ -590,6 +592,35 @@ FString strbin1 (const char *start)
|
|||
return result;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CleanseString
|
||||
//
|
||||
// Does some mild sanity checking on a string: If it ends with an incomplete
|
||||
// color escape, the escape is removed.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void CleanseString(char *str)
|
||||
{
|
||||
char *escape = strrchr(str, TEXTCOLOR_ESCAPE);
|
||||
if (escape != NULL)
|
||||
{
|
||||
if (escape[1] == '\0')
|
||||
{
|
||||
*escape = '\0';
|
||||
}
|
||||
else if (escape[1] == '[')
|
||||
{
|
||||
char *close = strchr(escape + 2, ']');
|
||||
if (close == NULL)
|
||||
{
|
||||
*escape = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExpandEnvVars
|
||||
|
|
|
@ -53,6 +53,7 @@ const char *myasctime ();
|
|||
|
||||
int strbin (char *str);
|
||||
FString strbin1 (const char *start);
|
||||
void CleanseString (char *str);
|
||||
|
||||
void CreatePath(const char * fn);
|
||||
|
||||
|
|
|
@ -251,7 +251,8 @@ bool FConfigFile::SetSection (const char *name, bool allowCreate)
|
|||
//
|
||||
// FConfigFile :: SetFirstSection
|
||||
//
|
||||
// Sets the current section to the first one in the file.
|
||||
// Sets the current section to the first one in the file. Returns
|
||||
// false if there are no sections.
|
||||
//
|
||||
//====================================================================
|
||||
|
||||
|
@ -270,7 +271,8 @@ bool FConfigFile::SetFirstSection ()
|
|||
//
|
||||
// FConfigFile :: SetNextSection
|
||||
//
|
||||
// Advances the current section to the next one in the file.
|
||||
// Advances the current section to the next one in the file. Returns
|
||||
// false if there are no more sections.
|
||||
//
|
||||
//====================================================================
|
||||
|
||||
|
@ -332,6 +334,43 @@ void FConfigFile::ClearCurrentSection ()
|
|||
}
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
//
|
||||
// FConfigFile :: DeleteCurrentSection
|
||||
//
|
||||
// Completely removes the current section. The current section is
|
||||
// advanced to the next section. Returns true if there is still a
|
||||
// current section.
|
||||
//
|
||||
//====================================================================
|
||||
|
||||
bool FConfigFile::DeleteCurrentSection()
|
||||
{
|
||||
if (CurrentSection != NULL)
|
||||
{
|
||||
FConfigSection *sec;
|
||||
|
||||
ClearCurrentSection();
|
||||
|
||||
// Find the preceding section.
|
||||
for (sec = Sections; sec != NULL && sec->Next != CurrentSection; sec = sec->Next)
|
||||
{ }
|
||||
|
||||
sec->Next = CurrentSection->Next;
|
||||
if (LastSectionPtr == &CurrentSection->Next)
|
||||
{
|
||||
LastSectionPtr = &sec->Next;
|
||||
}
|
||||
|
||||
CurrentSection->~FConfigSection();
|
||||
delete[] (char *)CurrentSection;
|
||||
|
||||
CurrentSection = sec->Next;
|
||||
return CurrentSection != NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//====================================================================
|
||||
//
|
||||
// FConfigFile :: ClearKey
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
bool SetNextSection ();
|
||||
const char *GetCurrentSection () const;
|
||||
void ClearCurrentSection ();
|
||||
bool DeleteCurrentSection ();
|
||||
void ClearKey (const char *key);
|
||||
|
||||
bool SectionIsEmpty ();
|
||||
|
|
|
@ -2525,9 +2525,6 @@ void D_DoomMain (void)
|
|||
|
||||
FActorInfo::StaticInit ();
|
||||
|
||||
// Now that all actors have been defined we can finally set up the weapon slots
|
||||
GameConfig->DoWeaponSetup (GameNames[gameinfo.gametype]);
|
||||
|
||||
// [GRB] Initialize player class list
|
||||
SetupPlayerClasses ();
|
||||
|
||||
|
|
|
@ -1963,15 +1963,16 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
BYTE who = ReadByte (stream);
|
||||
|
||||
s = ReadString (stream);
|
||||
CleanseString (s);
|
||||
if (((who & 1) == 0) || players[player].userinfo.team == TEAM_NONE)
|
||||
{ // Said to everyone
|
||||
if (who & 2)
|
||||
{
|
||||
Printf (PRINT_CHAT, TEXTCOLOR_BOLD "* %s%s\n", name, s);
|
||||
Printf (PRINT_CHAT, TEXTCOLOR_BOLD "* %s" TEXTCOLOR_BOLD "%s" TEXTCOLOR_BOLD "\n", name, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf (PRINT_CHAT, "%s: %s\n", name, s);
|
||||
Printf (PRINT_CHAT, "%s" TEXTCOLOR_CHAT ": %s" TEXTCOLOR_CHAT "\n", name, s);
|
||||
}
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, gameinfo.chatSound, 1, ATTN_NONE);
|
||||
}
|
||||
|
@ -1979,11 +1980,11 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
{ // Said only to members of the player's team
|
||||
if (who & 2)
|
||||
{
|
||||
Printf (PRINT_TEAMCHAT, TEXTCOLOR_BOLD "* (%s)%s\n", name, s);
|
||||
Printf (PRINT_TEAMCHAT, TEXTCOLOR_BOLD "* (%s" TEXTCOLOR_BOLD ")%s" TEXTCOLOR_BOLD "\n", name, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
Printf (PRINT_TEAMCHAT, "(%s): %s\n", name, s);
|
||||
Printf (PRINT_TEAMCHAT, "(%s" TEXTCOLOR_TEAMCHAT "): %s" TEXTCOLOR_TEAMCHAT "\n", name, s);
|
||||
}
|
||||
S_Sound (CHAN_VOICE | CHAN_UI, gameinfo.chatSound, 1, ATTN_NONE);
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "teaminfo.h"
|
||||
#include "r_translate.h"
|
||||
#include "templates.h"
|
||||
#include "cmdlib.h"
|
||||
|
||||
static FRandom pr_pickteam ("PickRandomTeam");
|
||||
|
||||
|
@ -698,10 +699,10 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
|
|||
{
|
||||
char oldname[MAXPLAYERNAME+1];
|
||||
|
||||
strncpy (oldname, info->netname, MAXPLAYERNAME);
|
||||
oldname[MAXPLAYERNAME] = 0;
|
||||
strcpy (oldname, info->netname);
|
||||
strncpy (info->netname, value, MAXPLAYERNAME);
|
||||
info->netname[MAXPLAYERNAME] = 0;
|
||||
CleanseString(info->netname);
|
||||
|
||||
if (update && strcmp (oldname, info->netname) != 0)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,16 @@ enum
|
|||
APMETA_Hexenarmor2,
|
||||
APMETA_Hexenarmor3,
|
||||
APMETA_Hexenarmor4,
|
||||
APMETA_Slot0,
|
||||
APMETA_Slot1,
|
||||
APMETA_Slot2,
|
||||
APMETA_Slot3,
|
||||
APMETA_Slot4,
|
||||
APMETA_Slot5,
|
||||
APMETA_Slot6,
|
||||
APMETA_Slot7,
|
||||
APMETA_Slot8,
|
||||
APMETA_Slot9,
|
||||
};
|
||||
|
||||
class player_t;
|
||||
|
|
|
@ -296,12 +296,12 @@ CCMD (turn180)
|
|||
|
||||
CCMD (weapnext)
|
||||
{
|
||||
SendItemUse = PickNextWeapon (&players[consoleplayer]);
|
||||
SendItemUse = LocalWeapons.PickNextWeapon (&players[consoleplayer]);
|
||||
}
|
||||
|
||||
CCMD (weapprev)
|
||||
{
|
||||
SendItemUse = PickPrevWeapon (&players[consoleplayer]);
|
||||
SendItemUse = LocalWeapons.PickPrevWeapon (&players[consoleplayer]);
|
||||
}
|
||||
|
||||
CCMD (invnext)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#define MAX_MANA 200
|
||||
|
||||
#define MAX_WEAPONS_PER_SLOT 8
|
||||
#define NUM_WEAPON_SLOTS 10
|
||||
|
||||
class player_t;
|
||||
|
@ -17,30 +16,39 @@ class AWeapon;
|
|||
class FWeaponSlot
|
||||
{
|
||||
public:
|
||||
FWeaponSlot ();
|
||||
void Clear ();
|
||||
FWeaponSlot &operator= (const FWeaponSlot &other) { Weapons = other.Weapons; return *this; }
|
||||
void Clear() { Weapons.Clear(); }
|
||||
bool AddWeapon (const char *type);
|
||||
bool AddWeapon (const PClass *type);
|
||||
void AddWeaponList (const char *list, bool clear);
|
||||
AWeapon *PickWeapon (player_t *player);
|
||||
int CountWeapons ();
|
||||
int Size () { return (int)Weapons.Size(); }
|
||||
int LocateWeapon (const PClass *type);
|
||||
|
||||
inline const PClass *GetWeapon (int index) const
|
||||
{
|
||||
return Weapons[index];
|
||||
if ((unsigned)index < Weapons.Size())
|
||||
{
|
||||
return Weapons[index].Type;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
friend AWeapon *PickNextWeapon (player_t *player);
|
||||
friend AWeapon *PickPrevWeapon (player_t *player);
|
||||
|
||||
friend struct FWeaponSlots;
|
||||
|
||||
private:
|
||||
const PClass *Weapons[MAX_WEAPONS_PER_SLOT];
|
||||
struct WeaponInfo
|
||||
{
|
||||
const PClass *Type;
|
||||
fixed_t Position;
|
||||
};
|
||||
void SetInitialPositions();
|
||||
void Sort();
|
||||
TArray<WeaponInfo> Weapons;
|
||||
};
|
||||
|
||||
AWeapon *PickNextWeapon (player_t *player);
|
||||
AWeapon *PickPrevWeapon (player_t *player);
|
||||
|
||||
// FWeaponSlots::AddDefaultWeapon return codes
|
||||
enum ESlotDef
|
||||
{
|
||||
|
@ -53,13 +61,20 @@ struct FWeaponSlots
|
|||
{
|
||||
FWeaponSlot Slots[NUM_WEAPON_SLOTS];
|
||||
|
||||
AWeapon *PickNextWeapon (player_t *player);
|
||||
AWeapon *PickPrevWeapon (player_t *player);
|
||||
|
||||
void Clear ();
|
||||
bool LocateWeapon (const PClass *type, int *const slot, int *const index);
|
||||
ESlotDef AddDefaultWeapon (int slot, const PClass *type);
|
||||
int RestoreSlots (FConfigFile &config);
|
||||
void SaveSlots (FConfigFile &config);
|
||||
void AddExtraWeapons();
|
||||
void SetFromPlayer(const PClass *type);
|
||||
void CompleteSetup(const PClass *type);
|
||||
int RestoreSlots (FConfigFile *config, const char *section);
|
||||
};
|
||||
|
||||
void P_PlaybackKeyConfWeapons();
|
||||
void P_SetLocalWeapons(AActor *player);
|
||||
extern FWeaponSlots LocalWeapons;
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -202,6 +217,13 @@ public:
|
|||
};
|
||||
|
||||
// A weapon is just that.
|
||||
enum
|
||||
{
|
||||
AWMETA_BASE = 0x72000,
|
||||
AWMETA_SlotNumber,
|
||||
AWMETA_SlotPriority,
|
||||
};
|
||||
|
||||
class AWeapon : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (AWeapon, AInventory)
|
||||
|
|
|
@ -25,6 +25,9 @@ IMPLEMENT_POINTY_CLASS (AWeapon)
|
|||
DECLARE_POINTER (SisterWeapon)
|
||||
END_POINTERS
|
||||
|
||||
FString WeaponSection;
|
||||
TArray<FString> KeyConfWeapons;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AWeapon :: Serialize
|
||||
|
@ -624,27 +627,22 @@ bool AWeaponGiver::TryPickup(AActor *&toucher)
|
|||
|
||||
FWeaponSlots LocalWeapons;
|
||||
|
||||
FWeaponSlot::FWeaponSlot ()
|
||||
{
|
||||
Clear ();
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: AddWeapon
|
||||
//
|
||||
// Adds a weapon to the end of the slot if it isn't already in it.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlot::Clear ()
|
||||
{
|
||||
for (int i = 0; i < MAX_WEAPONS_PER_SLOT; i++)
|
||||
{
|
||||
Weapons[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool FWeaponSlot::AddWeapon (const char *type)
|
||||
bool FWeaponSlot::AddWeapon(const char *type)
|
||||
{
|
||||
return AddWeapon (PClass::FindClass (type));
|
||||
}
|
||||
|
||||
bool FWeaponSlot::AddWeapon (const PClass *type)
|
||||
bool FWeaponSlot::AddWeapon(const PClass *type)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
if (type == NULL)
|
||||
{
|
||||
|
@ -657,41 +655,104 @@ bool FWeaponSlot::AddWeapon (const PClass *type)
|
|||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_WEAPONS_PER_SLOT; i++)
|
||||
for (i = 0; i < Weapons.Size(); i++)
|
||||
{
|
||||
if (Weapons[i] == type)
|
||||
if (Weapons[i].Type == type)
|
||||
return true; // Already present
|
||||
if (Weapons[i] == NULL)
|
||||
break;
|
||||
}
|
||||
if (i == MAX_WEAPONS_PER_SLOT)
|
||||
{ // This slot is full
|
||||
return false;
|
||||
}
|
||||
Weapons[i] = type;
|
||||
WeaponInfo info = { type, -1 };
|
||||
Weapons.Push(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
AWeapon *FWeaponSlot::PickWeapon (player_t *player)
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: AddWeaponList
|
||||
//
|
||||
// Appends all the weapons from the space-delimited list to this slot.
|
||||
// Set clear to true to remove any weapons already in this slot first.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlot :: AddWeaponList(const char *list, bool clear)
|
||||
{
|
||||
FString copy(list);
|
||||
char *buff = copy.LockBuffer();
|
||||
char *tok;
|
||||
|
||||
if (clear)
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
tok = strtok(buff, " ");
|
||||
while (tok != NULL)
|
||||
{
|
||||
AddWeapon(tok);
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: LocateWeapon
|
||||
//
|
||||
// Returns the index for the specified weapon in this slot, or -1 if it isn't
|
||||
// in this slot.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int FWeaponSlot::LocateWeapon(const PClass *type)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < Weapons.Size(); ++i)
|
||||
{
|
||||
if (Weapons[i].Type == type)
|
||||
{
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: PickWeapon
|
||||
//
|
||||
// Picks a weapon from this slot. If no weapon is selected in this slot,
|
||||
// or the first weapon in this slot is selected, returns the last weapon.
|
||||
// Otherwise, returns the previous weapon in this slot. This means
|
||||
// precedence is given to the last weapon in the slot, which by convention
|
||||
// is probably the strongest. Does not return weapons you have no ammo
|
||||
// for or which you do not possess.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AWeapon *FWeaponSlot::PickWeapon(player_t *player)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
// Does this slot even have any weapons?
|
||||
if (Weapons.Size() == 0)
|
||||
{
|
||||
return player->ReadyWeapon;
|
||||
}
|
||||
if (player->ReadyWeapon != NULL)
|
||||
{
|
||||
for (i = 0; i < MAX_WEAPONS_PER_SLOT; i++)
|
||||
for (i = 0; i < Weapons.Size(); i++)
|
||||
{
|
||||
if (Weapons[i] == player->ReadyWeapon->GetClass() ||
|
||||
if (Weapons[i].Type == player->ReadyWeapon->GetClass() ||
|
||||
(player->ReadyWeapon->WeaponFlags & WIF_POWERED_UP &&
|
||||
player->ReadyWeapon->SisterWeapon != NULL &&
|
||||
player->ReadyWeapon->SisterWeapon->GetClass() == Weapons[i]))
|
||||
player->ReadyWeapon->SisterWeapon->GetClass() == Weapons[i].Type))
|
||||
{
|
||||
for (j = (unsigned)(i - 1) % MAX_WEAPONS_PER_SLOT;
|
||||
for (j = (unsigned)(i - 1) % Weapons.Size();
|
||||
j != i;
|
||||
j = (unsigned)(j - 1) % MAX_WEAPONS_PER_SLOT)
|
||||
j = (unsigned)(j - 1) % Weapons.Size())
|
||||
{
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory (Weapons[j]));
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory(Weapons[j].Type));
|
||||
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo (AWeapon::EitherFire, false))
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
|
@ -699,11 +760,11 @@ AWeapon *FWeaponSlot::PickWeapon (player_t *player)
|
|||
}
|
||||
}
|
||||
}
|
||||
for (i = MAX_WEAPONS_PER_SLOT - 1; i >= 0; i--)
|
||||
for (i = Weapons.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory (Weapons[i]));
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory(Weapons[i].Type));
|
||||
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo (AWeapon::EitherFire, false))
|
||||
if (weap != NULL && weap->IsKindOf(RUNTIME_CLASS(AWeapon)) && weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
|
@ -711,17 +772,85 @@ AWeapon *FWeaponSlot::PickWeapon (player_t *player)
|
|||
return player->ReadyWeapon;
|
||||
}
|
||||
|
||||
void FWeaponSlots::Clear ()
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: SetInitialPositions
|
||||
//
|
||||
// Fills in the position field for every weapon currently in the slot based
|
||||
// on its position in the slot. These are not scaled to [0,1] so that extra
|
||||
// weapons can use those values to go to the start or end of the slot.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlot::SetInitialPositions()
|
||||
{
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
unsigned int size = Weapons.Size(), i;
|
||||
|
||||
if (size == 1)
|
||||
{
|
||||
Slots[i].Clear ();
|
||||
Weapons[0].Position = 0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < size; ++i)
|
||||
{
|
||||
Weapons[i].Position = i * 0xFF00 / (size - 1) + 0x80;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlot :: Sort
|
||||
//
|
||||
// Rearranges the weapons by their position field.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlot::Sort()
|
||||
{
|
||||
// This does not use qsort(), because the sort should be stable, and
|
||||
// there is no guarantee that qsort() is stable. This insertion sort
|
||||
// should be fine.
|
||||
int i, j;
|
||||
|
||||
for (i = 1; i < (int)Weapons.Size(); ++i)
|
||||
{
|
||||
fixed_t pos = Weapons[i].Position;
|
||||
const PClass *type = Weapons[i].Type;
|
||||
for (j = i - 1; j >= 0 && Weapons[j].Position > pos; --j)
|
||||
{
|
||||
Weapons[j + 1] = Weapons[j];
|
||||
}
|
||||
Weapons[j + 1].Type = type;
|
||||
Weapons[j + 1].Position = pos;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: Clear
|
||||
//
|
||||
// Removes all weapons from every slot.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlots::Clear()
|
||||
{
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
Slots[i].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: AddDefaultWeapon
|
||||
//
|
||||
// If the weapon already exists in a slot, don't add it. If it doesn't,
|
||||
// then add it to the specified slot. False is returned if the weapon was
|
||||
// not in a slot and could not be added. True is returned otherwise.
|
||||
// then add it to the specified slot.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
ESlotDef FWeaponSlots::AddDefaultWeapon (int slot, const PClass *type)
|
||||
{
|
||||
|
@ -739,43 +868,59 @@ ESlotDef FWeaponSlots::AddDefaultWeapon (int slot, const PClass *type)
|
|||
return SLOTDEF_Exists;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: LocateWeapon
|
||||
//
|
||||
// Returns true if the weapon is in a slot, false otherwise. If the weapon
|
||||
// is found, it can also optionally return the slot and index for it.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FWeaponSlots::LocateWeapon (const PClass *type, int *const slot, int *const index)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < NUM_WEAPON_SLOTS; i++)
|
||||
{
|
||||
for (j = 0; j < MAX_WEAPONS_PER_SLOT; j++)
|
||||
j = Slots[i].LocateWeapon(type);
|
||||
if (j >= 0)
|
||||
{
|
||||
if (Slots[i].Weapons[j] == type)
|
||||
{
|
||||
if (slot != NULL) *slot = i;
|
||||
if (index != NULL) *index = j;
|
||||
return true;
|
||||
}
|
||||
else if (Slots[i].Weapons[j] == NULL)
|
||||
{ // No more weapons in this slot, so try the next
|
||||
break;
|
||||
}
|
||||
if (slot != NULL) *slot = i;
|
||||
if (index != NULL) *index = j;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool FindMostRecentWeapon (player_t *player, int *slot, int *index)
|
||||
//===========================================================================
|
||||
//
|
||||
// FindMostRecentWeapon
|
||||
//
|
||||
// Locates the slot and index for the most recently selected weapon. If the
|
||||
// player is in the process of switching to a new weapon, that is the most
|
||||
// recently selected weapon. Otherwise, the current weapon is the most recent
|
||||
// weapon.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static bool FindMostRecentWeapon(player_t *player, int *slot, int *index)
|
||||
{
|
||||
if (player->PendingWeapon != WP_NOCHANGE)
|
||||
{
|
||||
return LocalWeapons.LocateWeapon (player->PendingWeapon->GetClass(), slot, index);
|
||||
return LocalWeapons.LocateWeapon(player->PendingWeapon->GetClass(), slot, index);
|
||||
}
|
||||
else if (player->ReadyWeapon != NULL)
|
||||
{
|
||||
AWeapon *weap = player->ReadyWeapon;
|
||||
if (!LocalWeapons.LocateWeapon (weap->GetClass(), slot, index))
|
||||
if (!LocalWeapons.LocateWeapon(weap->GetClass(), slot, index))
|
||||
{
|
||||
// If the current weapon wasn't found and is powered up,
|
||||
// look for its non-powered up version.
|
||||
if (weap->WeaponFlags & WIF_POWERED_UP && weap->SisterWeaponType != NULL)
|
||||
{
|
||||
return LocalWeapons.LocateWeapon (weap->SisterWeaponType, slot, index);
|
||||
return LocalWeapons.LocateWeapon(weap->SisterWeaponType, slot, index);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -787,7 +932,17 @@ static bool FindMostRecentWeapon (player_t *player, int *slot, int *index)
|
|||
}
|
||||
}
|
||||
|
||||
AWeapon *PickNextWeapon (player_t *player)
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: PickNextWeapon
|
||||
//
|
||||
// Returns the "next" weapon for this player. If the current weapon is not
|
||||
// in a slot, then it just returns that weapon, since there's nothing to
|
||||
// consider it relative to.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AWeapon *FWeaponSlots::PickNextWeapon(player_t *player)
|
||||
{
|
||||
int startslot, startindex;
|
||||
|
||||
|
@ -795,35 +950,52 @@ AWeapon *PickNextWeapon (player_t *player)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
if (player->ReadyWeapon == NULL || FindMostRecentWeapon (player, &startslot, &startindex))
|
||||
if (player->ReadyWeapon == NULL || FindMostRecentWeapon(player, &startslot, &startindex))
|
||||
{
|
||||
int start;
|
||||
int i;
|
||||
int slot;
|
||||
int index;
|
||||
|
||||
if (player->ReadyWeapon == NULL)
|
||||
{
|
||||
startslot = NUM_WEAPON_SLOTS - 1;
|
||||
startindex = MAX_WEAPONS_PER_SLOT - 1;
|
||||
startindex = Slots[startslot].Size() - 1;
|
||||
}
|
||||
start = startslot * MAX_WEAPONS_PER_SLOT + startindex;
|
||||
|
||||
for (i = 1; i < NUM_WEAPON_SLOTS * MAX_WEAPONS_PER_SLOT + 1; i++)
|
||||
slot = startslot;
|
||||
index = startindex;
|
||||
do
|
||||
{
|
||||
int slot = (unsigned)((start + i) / MAX_WEAPONS_PER_SLOT) % NUM_WEAPON_SLOTS;
|
||||
int index = (unsigned)(start + i) % MAX_WEAPONS_PER_SLOT;
|
||||
const PClass *type = LocalWeapons.Slots[slot].Weapons[index];
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory (type));
|
||||
|
||||
if (weap != NULL && weap->CheckAmmo (AWeapon::EitherFire, false))
|
||||
if (++index >= Slots[slot].Size())
|
||||
{
|
||||
index = 0;
|
||||
if (++slot >= NUM_WEAPON_SLOTS)
|
||||
{
|
||||
slot = 0;
|
||||
}
|
||||
}
|
||||
const PClass *type = LocalWeapons.Slots[slot].GetWeapon(index);
|
||||
AWeapon *weap = static_cast<AWeapon *>(player->mo->FindInventory(type));
|
||||
if (weap != NULL && weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
while (slot != startslot || index != startindex);
|
||||
}
|
||||
return player->ReadyWeapon;
|
||||
}
|
||||
|
||||
AWeapon *PickPrevWeapon (player_t *player)
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: PickPrevWeapon
|
||||
//
|
||||
// Returns the "previous" weapon for this player. If the current weapon is
|
||||
// not in a slot, then it just returns that weapon, since there's nothing to
|
||||
// consider it relative to.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
AWeapon *FWeaponSlots::PickPrevWeapon (player_t *player)
|
||||
{
|
||||
int startslot, startindex;
|
||||
|
||||
|
@ -833,79 +1005,250 @@ AWeapon *PickPrevWeapon (player_t *player)
|
|||
}
|
||||
if (player->ReadyWeapon == NULL || FindMostRecentWeapon (player, &startslot, &startindex))
|
||||
{
|
||||
int start;
|
||||
int i;
|
||||
int slot;
|
||||
int index;
|
||||
|
||||
if (player->ReadyWeapon == NULL)
|
||||
{
|
||||
startslot = 0;
|
||||
startindex = 0;
|
||||
}
|
||||
start = startslot * MAX_WEAPONS_PER_SLOT + startindex;
|
||||
|
||||
for (i = 1; i < NUM_WEAPON_SLOTS * MAX_WEAPONS_PER_SLOT + 1; i++)
|
||||
slot = startslot;
|
||||
index = startindex;
|
||||
do
|
||||
{
|
||||
int slot = start - i;
|
||||
if (slot < 0)
|
||||
slot += NUM_WEAPON_SLOTS * MAX_WEAPONS_PER_SLOT;
|
||||
int index = slot % MAX_WEAPONS_PER_SLOT;
|
||||
slot /= MAX_WEAPONS_PER_SLOT;
|
||||
const PClass *type = LocalWeapons.Slots[slot].Weapons[index];
|
||||
AWeapon *weap = static_cast<AWeapon *> (player->mo->FindInventory (type));
|
||||
|
||||
if (weap != NULL && weap->CheckAmmo (AWeapon::EitherFire, false))
|
||||
if (--index < 0)
|
||||
{
|
||||
if (--slot < 0)
|
||||
{
|
||||
slot = NUM_WEAPON_SLOTS - 1;
|
||||
}
|
||||
index = Slots[slot].Size() - 1;
|
||||
}
|
||||
const PClass *type = LocalWeapons.Slots[slot].GetWeapon(index);
|
||||
AWeapon *weap = static_cast<AWeapon *>(player->mo->FindInventory(type));
|
||||
if (weap != NULL && weap->CheckAmmo(AWeapon::EitherFire, false))
|
||||
{
|
||||
return weap;
|
||||
}
|
||||
}
|
||||
while (slot != startslot || index != startindex);
|
||||
}
|
||||
return player->ReadyWeapon;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: AddExtraWeapons
|
||||
//
|
||||
// For every weapon class for the current game, add it to its desired slot
|
||||
// and position within the slot. Does not first clear the slots.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlots::AddExtraWeapons()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
// Set fractional positions for current weapons.
|
||||
for (i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
Slots[i].SetInitialPositions();
|
||||
}
|
||||
|
||||
// Append extra weapons to the slots.
|
||||
for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
|
||||
{
|
||||
PClass *cls = PClass::m_Types[i];
|
||||
|
||||
if (cls->ActorInfo != NULL &&
|
||||
(cls->ActorInfo->GameFilter == GAME_Any || (cls->ActorInfo->GameFilter & gameinfo.gametype)) &&
|
||||
cls->ActorInfo->Replacement == NULL && // Replaced weapons don't get slotted.
|
||||
cls->IsDescendantOf(RUNTIME_CLASS(AWeapon)) &&
|
||||
!LocateWeapon(cls, NULL, NULL) // Don't duplicate it if it's already present.
|
||||
)
|
||||
{
|
||||
int slot = cls->Meta.GetMetaInt(AWMETA_SlotNumber, -1);
|
||||
if ((unsigned)slot < NUM_WEAPON_SLOTS)
|
||||
{
|
||||
fixed_t position = cls->Meta.GetMetaFixed(AWMETA_SlotPriority, INT_MAX);
|
||||
FWeaponSlot::WeaponInfo info = { cls, position };
|
||||
Slots[slot].Weapons.Push(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now resort every slot to put the new weapons in their proper places.
|
||||
for (i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
Slots[i].Sort();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: CompleteSetup
|
||||
//
|
||||
// Sets up local weapon slots in this order:
|
||||
// 1. Use slots from player class.
|
||||
// 2. Add extra weapons that specify their own slot.
|
||||
// 3. Run KEYCONF weapon commands, affecting slots accordingly.
|
||||
// 4. Read config slots, overriding current slots. If WeaponSection is set,
|
||||
// then [<WeaponSection>.<PlayerClass>.Weapons] is tried, followed by
|
||||
// [<WeaponSection>.Weapons] if that did not exist. If WeaponSection is
|
||||
// empty, then the slots are read from [<PlayerClass>.Weapons].
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlots::CompleteSetup(const PClass *type)
|
||||
{
|
||||
SetFromPlayer(type);
|
||||
AddExtraWeapons();
|
||||
P_PlaybackKeyConfWeapons();
|
||||
if (WeaponSection.IsNotEmpty())
|
||||
{
|
||||
FString sectionclass(WeaponSection);
|
||||
sectionclass << '.' << type->TypeName.GetChars();
|
||||
if (RestoreSlots(GameConfig, sectionclass) == 0)
|
||||
{
|
||||
RestoreSlots(GameConfig, WeaponSection);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RestoreSlots(GameConfig, type->TypeName.GetChars());
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: SetFromPlayer
|
||||
//
|
||||
// Sets all weapon slots according to the player class.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FWeaponSlots::SetFromPlayer(const PClass *type)
|
||||
{
|
||||
Clear();
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
const char *str = type->Meta.GetMetaString(APMETA_Slot0 + i);
|
||||
if (str != NULL)
|
||||
{
|
||||
Slots[i].AddWeaponList(str, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FWeaponSlots :: RestoreSlots
|
||||
//
|
||||
// Reads slots from a config section. Any slots in the section override
|
||||
// existing slot settings, while slots not present in the config are
|
||||
// unaffected. Returns the number of slots read.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
int FWeaponSlots::RestoreSlots(FConfigFile *config, const char *section)
|
||||
{
|
||||
FString section_name(section);
|
||||
const char *key, *value;
|
||||
int slotsread = 0;
|
||||
|
||||
section_name += ".Weapons";
|
||||
if (!config->SetSection(section_name))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
while (config->NextInSection (key, value))
|
||||
{
|
||||
if (strnicmp (key, "Slot[", 5) != 0 ||
|
||||
key[5] < '0' ||
|
||||
key[5] > '0'+NUM_WEAPON_SLOTS ||
|
||||
key[6] != ']' ||
|
||||
key[7] != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Slots[key[5] - '0'].AddWeaponList(value, true);
|
||||
slotsread++;
|
||||
}
|
||||
return slotsread;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CCMD setslot
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
CCMD (setslot)
|
||||
{
|
||||
int slot, i;
|
||||
|
||||
if (ParsingKeyConf && WeaponSection.IsEmpty())
|
||||
{
|
||||
Printf ("You need to use weaponsection before using setslot\n");
|
||||
return;
|
||||
}
|
||||
int slot;
|
||||
|
||||
if (argv.argc() < 2 || (slot = atoi (argv[1])) >= NUM_WEAPON_SLOTS)
|
||||
{
|
||||
Printf ("Usage: setslot [slot] [weapons]\nCurrent slot assignments:\n");
|
||||
for (slot = 0; slot < NUM_WEAPON_SLOTS; ++slot)
|
||||
Printf("Usage: setslot [slot] [weapons]\nCurrent slot assignments:\n");
|
||||
if (players[consoleplayer].mo != NULL)
|
||||
{
|
||||
Printf (" Slot %d:", slot);
|
||||
for (i = 0;
|
||||
i < MAX_WEAPONS_PER_SLOT && LocalWeapons.Slots[slot].GetWeapon(i) != NULL;
|
||||
++i)
|
||||
FString config(GameConfig->GetConfigPath(false));
|
||||
Printf(TEXTCOLOR_BLUE "Add the following to " TEXTCOLOR_ORANGE "%s" TEXTCOLOR_BLUE
|
||||
" to retain these bindings:\n" TEXTCOLOR_NORMAL "[", config.GetChars());
|
||||
if (WeaponSection.IsNotEmpty())
|
||||
{
|
||||
Printf (" %s", LocalWeapons.Slots[slot].GetWeapon(i)->TypeName.GetChars());
|
||||
Printf("%s.", WeaponSection.GetChars());
|
||||
}
|
||||
Printf("%s.Weapons]\n", players[consoleplayer].mo->GetClass()->TypeName.GetChars());
|
||||
}
|
||||
for (int i = 1; i <= NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
int slot = i % NUM_WEAPON_SLOTS;
|
||||
if (LocalWeapons.Slots[slot].Size() > 0)
|
||||
{
|
||||
Printf("Slot[%d]=", slot);
|
||||
for (int j = 0; j < LocalWeapons.Slots[slot].Size(); ++j)
|
||||
{
|
||||
Printf("%s ", LocalWeapons.Slots[slot].GetWeapon(j)->TypeName.GetChars());
|
||||
}
|
||||
Printf("\n");
|
||||
}
|
||||
Printf ("\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LocalWeapons.Slots[slot].Clear();
|
||||
if (argv.argc() == 2)
|
||||
if (ParsingKeyConf)
|
||||
{
|
||||
Printf ("Slot %d cleared\n", slot);
|
||||
KeyConfWeapons.Push(argv.args());
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 2; i < argv.argc(); ++i)
|
||||
LocalWeapons.Slots[slot].Clear();
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
if (!LocalWeapons.Slots[slot].AddWeapon (argv[i]))
|
||||
Printf ("Slot %d cleared\n", slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 2; i < argv.argc(); ++i)
|
||||
{
|
||||
Printf ("Could not add %s to slot %d\n", argv[i], slot);
|
||||
if (!LocalWeapons.Slots[slot].AddWeapon (argv[i]))
|
||||
{
|
||||
Printf ("Could not add %s to slot %d\n", argv[i], slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CCMD addslot
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
CCMD (addslot)
|
||||
{
|
||||
size_t slot;
|
||||
|
@ -916,61 +1259,39 @@ CCMD (addslot)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!LocalWeapons.Slots[slot].AddWeapon (argv[2]))
|
||||
if (ParsingKeyConf)
|
||||
{
|
||||
Printf ("Could not add %s to slot %zu\n", argv[2], slot);
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (weaponsection)
|
||||
{
|
||||
if (argv.argc() != 2)
|
||||
{
|
||||
Printf ("Usage: weaponsection <ini name>\n");
|
||||
KeyConfWeapons.Push(argv.args());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Limit the section name to 32 chars
|
||||
if (strlen(argv[1]) > 32)
|
||||
if (!LocalWeapons.Slots[slot].AddWeapon (argv[2]))
|
||||
{
|
||||
argv[1][32] = 0;
|
||||
}
|
||||
WeaponSection = argv[1];
|
||||
|
||||
// If the ini already has definitions for this section, load them
|
||||
char fullSection[32*3];
|
||||
char *tackOn;
|
||||
|
||||
if (gameinfo.gametype == GAME_Hexen)
|
||||
{
|
||||
strcpy (fullSection, "Hexen");
|
||||
tackOn = fullSection + 5;
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Heretic)
|
||||
{
|
||||
strcpy (fullSection, "Heretic");
|
||||
tackOn = fullSection + 7;
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
strcpy (fullSection, "Strife");
|
||||
tackOn = fullSection + 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (fullSection, "Doom");
|
||||
tackOn = fullSection + 4;
|
||||
}
|
||||
|
||||
mysnprintf (tackOn, countof(fullSection) - (tackOn - fullSection),
|
||||
".%s.WeaponSlots", WeaponSection.GetChars());
|
||||
if (GameConfig->SetSection (fullSection))
|
||||
{
|
||||
LocalWeapons.RestoreSlots (*GameConfig);
|
||||
Printf ("Could not add %s to slot %zu\n", argv[2], slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CCMD weaponsection
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
CCMD (weaponsection)
|
||||
{
|
||||
if (argv.argc() > 1)
|
||||
{
|
||||
WeaponSection = argv[1];
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CCMD addslotdefault
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
CCMD (addslotdefault)
|
||||
{
|
||||
const PClass *type;
|
||||
|
@ -982,113 +1303,58 @@ CCMD (addslotdefault)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ParsingKeyConf && WeaponSection.IsEmpty())
|
||||
{
|
||||
Printf ("You need to use weaponsection before using addslotdefault\n");
|
||||
return;
|
||||
}
|
||||
|
||||
type = PClass::FindClass (argv[2]);
|
||||
if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AWeapon)))
|
||||
{
|
||||
Printf ("%s is not a weapon\n", argv[2]);
|
||||
}
|
||||
|
||||
switch (LocalWeapons.AddDefaultWeapon (slot, type))
|
||||
if (ParsingKeyConf)
|
||||
{
|
||||
case SLOTDEF_Full:
|
||||
Printf ("Could not add %s to slot %d\n", argv[2], slot);
|
||||
break;
|
||||
|
||||
case SLOTDEF_Added:
|
||||
break;
|
||||
|
||||
case SLOTDEF_Exists:
|
||||
break;
|
||||
KeyConfWeapons.Push(argv.args());
|
||||
}
|
||||
}
|
||||
|
||||
int FWeaponSlots::RestoreSlots (FConfigFile &config)
|
||||
{
|
||||
char buff[MAX_WEAPONS_PER_SLOT*64];
|
||||
const char *key, *value;
|
||||
int slot;
|
||||
int slotsread = 0;
|
||||
|
||||
buff[sizeof(buff)-1] = 0;
|
||||
|
||||
for (slot = 0; slot < NUM_WEAPON_SLOTS; ++slot)
|
||||
else
|
||||
{
|
||||
Slots[slot].Clear ();
|
||||
}
|
||||
|
||||
while (config.NextInSection (key, value))
|
||||
{
|
||||
if (strnicmp (key, "Slot[", 5) != 0 ||
|
||||
key[5] < '0' ||
|
||||
key[5] > '0'+NUM_WEAPON_SLOTS ||
|
||||
key[6] != ']' ||
|
||||
key[7] != 0)
|
||||
switch (LocalWeapons.AddDefaultWeapon (slot, type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
slot = key[5] - '0';
|
||||
strncpy (buff, value, sizeof(buff)-1);
|
||||
char *tok;
|
||||
case SLOTDEF_Full:
|
||||
Printf ("Could not add %s to slot %d\n", argv[2], slot);
|
||||
break;
|
||||
|
||||
Slots[slot].Clear ();
|
||||
tok = strtok (buff, " ");
|
||||
while (tok != NULL)
|
||||
{
|
||||
Slots[slot].AddWeapon (tok);
|
||||
tok = strtok (NULL, " ");
|
||||
}
|
||||
slotsread++;
|
||||
}
|
||||
return slotsread;
|
||||
}
|
||||
case SLOTDEF_Added:
|
||||
break;
|
||||
|
||||
void FWeaponSlots::SaveSlots (FConfigFile &config)
|
||||
{
|
||||
char buff[MAX_WEAPONS_PER_SLOT*64];
|
||||
char keyname[16];
|
||||
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (int j = 0; j < MAX_WEAPONS_PER_SLOT; ++j)
|
||||
{
|
||||
if (Slots[i].Weapons[j] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
buff[index++] = ' ';
|
||||
}
|
||||
const char *name = Slots[i].Weapons[j]->TypeName.GetChars();
|
||||
strcpy (buff+index, name);
|
||||
index += (int)strlen (name);
|
||||
}
|
||||
if (index > 0)
|
||||
{
|
||||
mysnprintf (keyname, countof(keyname), "Slot[%d]", i);
|
||||
config.SetValueForKey (keyname, buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int FWeaponSlot::CountWeapons ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_WEAPONS_PER_SLOT; ++i)
|
||||
{
|
||||
if (Weapons[i] == NULL)
|
||||
{
|
||||
case SLOTDEF_Exists:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// P_PlaybackKeyConfWeapons
|
||||
//
|
||||
// Executes the weapon-related commands from a KEYCONF lump.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void P_PlaybackKeyConfWeapons()
|
||||
{
|
||||
for (unsigned int i = 0; i < KeyConfWeapons.Size(); ++i)
|
||||
{
|
||||
FString cmd(KeyConfWeapons[i]);
|
||||
AddCommandString(cmd.LockBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CCMD dumpslots
|
||||
//
|
||||
// Dumps a config-friendly listing of the current slot assignments.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
CCMD (dumpslots)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -414,7 +414,7 @@ void DSBarInfo::doCommands(SBarInfoBlock &block, int xOffset, int yOffset, int a
|
|||
if((cmd.flags & DRAWIMAGE_WEAPONSLOT)) //weaponslots
|
||||
{
|
||||
drawAlt = 1; //draw off state until we know we have something.
|
||||
for (int i = 0; i < MAX_WEAPONS_PER_SLOT; i++)
|
||||
for (int i = 0; i < LocalWeapons.Slots[cmd.value].Size(); i++)
|
||||
{
|
||||
const PClass *weap = LocalWeapons.Slots[cmd.value].GetWeapon(i);
|
||||
if(weap == NULL)
|
||||
|
|
|
@ -506,7 +506,7 @@ static int DrawAmmo(player_t * CPlayer, int x, int y)
|
|||
// Do not check for actual presence in the inventory!
|
||||
// We want to show all ammo types that can be used by
|
||||
// the weapons in the weapon slots.
|
||||
for (k=0;k<NUM_WEAPON_SLOTS;k++) for(j=0;j<MAX_WEAPONS_PER_SLOT;j++)
|
||||
for (k=0;k<NUM_WEAPON_SLOTS;k++) for(j=0;j<LocalWeapons.Slots[k].Size();j++)
|
||||
{
|
||||
const PClass * weap = LocalWeapons.Slots[k].GetWeapon(j);
|
||||
|
||||
|
@ -636,7 +636,7 @@ static void DrawWeapons(player_t * CPlayer, int x, int y)
|
|||
}
|
||||
|
||||
// And now everything in the weapon slots back to front
|
||||
for (k=NUM_WEAPON_SLOTS-1;k>=0;k--) for(j=MAX_WEAPONS_PER_SLOT-1;j>=0;j--)
|
||||
for (k=NUM_WEAPON_SLOTS-1;k>=0;k--) for(j=LocalWeapons.Slots[k].Size()-1;j>=0;j--)
|
||||
{
|
||||
const PClass * weap = LocalWeapons.Slots[k].GetWeapon(j);
|
||||
if (weap)
|
||||
|
|
|
@ -73,8 +73,6 @@ EXTERN_CVAR (Color, am_cdwallcolor)
|
|||
EXTERN_CVAR (Float, spc_amp)
|
||||
EXTERN_CVAR (Bool, wi_percents)
|
||||
|
||||
FString WeaponSection;
|
||||
|
||||
FGameConfigFile::FGameConfigFile ()
|
||||
{
|
||||
FString pathname;
|
||||
|
@ -222,16 +220,6 @@ void FGameConfigFile::DoGlobalSetup ()
|
|||
noblitter->ResetToDefault ();
|
||||
}
|
||||
}
|
||||
if (last < 201)
|
||||
{
|
||||
// Be sure the Hexen fourth weapons are assigned to slot 4
|
||||
// If this section does not already exist, then they will be
|
||||
// assigned by SetupWeaponList().
|
||||
if (SetSection ("Hexen.WeaponSlots"))
|
||||
{
|
||||
SetValueForKey ("Slot[4]", "FWeapQuietus CWeapWraithverge MWeapBloodscourge");
|
||||
}
|
||||
}
|
||||
if (last < 202)
|
||||
{
|
||||
// Make sure the Hexen hotkeys are accessible by default.
|
||||
|
@ -271,6 +259,28 @@ void FGameConfigFile::DoGlobalSetup ()
|
|||
precache->ResetToDefault();
|
||||
}
|
||||
}
|
||||
if (last < 208)
|
||||
{ // Weapon sections are no longer used, so tidy up the config by deleting them.
|
||||
const char *name;
|
||||
size_t namelen;
|
||||
bool more;
|
||||
|
||||
more = SetFirstSection();
|
||||
while (more)
|
||||
{
|
||||
name = GetCurrentSection();
|
||||
if (name != NULL &&
|
||||
(namelen = strlen(name)) > 12 &&
|
||||
strcmp(name + namelen - 12, ".WeaponSlots") == 0)
|
||||
{
|
||||
more = DeleteCurrentSection();
|
||||
}
|
||||
else
|
||||
{
|
||||
more = SetNextSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,17 +386,6 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
|
|||
}
|
||||
}
|
||||
|
||||
// Separated from DoGameSetup because it needs all the weapons properly defined
|
||||
void FGameConfigFile::DoWeaponSetup (const char *gamename)
|
||||
{
|
||||
strncpy (subsection, "WeaponSlots", sublen);
|
||||
|
||||
if (!SetSection (section) || !LocalWeapons.RestoreSlots (*this))
|
||||
{
|
||||
SetupWeaponList (gamename);
|
||||
}
|
||||
}
|
||||
|
||||
void FGameConfigFile::ReadNetVars ()
|
||||
{
|
||||
strncpy (subsection, "NetServerInfo", sublen);
|
||||
|
@ -460,18 +459,6 @@ void FGameConfigFile::ArchiveGameData (const char *gamename)
|
|||
strncpy (subsection, "DoubleBindings", sublen);
|
||||
SetSection (section, true);
|
||||
C_ArchiveBindings (this, true);
|
||||
|
||||
if (WeaponSection.IsEmpty())
|
||||
{
|
||||
strncpy (subsection, "WeaponSlots", sublen);
|
||||
}
|
||||
else
|
||||
{
|
||||
mysnprintf (subsection, sublen, "%s.WeaponSlots", WeaponSection.GetChars());
|
||||
}
|
||||
SetSection (section, true);
|
||||
ClearCurrentSection ();
|
||||
LocalWeapons.SaveSlots (*this);
|
||||
}
|
||||
|
||||
void FGameConfigFile::ArchiveGlobalData ()
|
||||
|
@ -676,79 +663,6 @@ void FGameConfigFile::SetRavenDefaults (bool isHexen)
|
|||
}
|
||||
}
|
||||
|
||||
void FGameConfigFile::SetupWeaponList (const char *gamename)
|
||||
{
|
||||
for (int i = 0; i < NUM_WEAPON_SLOTS; ++i)
|
||||
{
|
||||
LocalWeapons.Slots[i].Clear ();
|
||||
}
|
||||
|
||||
if (strcmp (gamename, "Heretic") == 0)
|
||||
{
|
||||
LocalWeapons.Slots[1].AddWeapon ("Staff");
|
||||
LocalWeapons.Slots[1].AddWeapon ("Gauntlets");
|
||||
LocalWeapons.Slots[2].AddWeapon ("GoldWand");
|
||||
LocalWeapons.Slots[3].AddWeapon ("Crossbow");
|
||||
LocalWeapons.Slots[4].AddWeapon ("Blaster");
|
||||
LocalWeapons.Slots[5].AddWeapon ("SkullRod");
|
||||
LocalWeapons.Slots[6].AddWeapon ("PhoenixRod");
|
||||
LocalWeapons.Slots[7].AddWeapon ("Mace");
|
||||
}
|
||||
else if (strcmp (gamename, "Hexen") == 0)
|
||||
{
|
||||
LocalWeapons.Slots[1].AddWeapon ("FWeapFist");
|
||||
LocalWeapons.Slots[2].AddWeapon ("FWeapAxe");
|
||||
LocalWeapons.Slots[3].AddWeapon ("FWeapHammer");
|
||||
LocalWeapons.Slots[4].AddWeapon ("FWeapQuietus");
|
||||
LocalWeapons.Slots[1].AddWeapon ("CWeapMace");
|
||||
LocalWeapons.Slots[2].AddWeapon ("CWeapStaff");
|
||||
LocalWeapons.Slots[3].AddWeapon ("CWeapFlame");
|
||||
LocalWeapons.Slots[4].AddWeapon ("CWeapWraithverge");
|
||||
LocalWeapons.Slots[1].AddWeapon ("MWeapWand");
|
||||
LocalWeapons.Slots[2].AddWeapon ("MWeapFrost");
|
||||
LocalWeapons.Slots[3].AddWeapon ("MWeapLightning");
|
||||
LocalWeapons.Slots[4].AddWeapon ("MWeapBloodscourge");
|
||||
}
|
||||
else if (strcmp (gamename, "Strife") == 0)
|
||||
{
|
||||
LocalWeapons.Slots[1].AddWeapon ("PunchDagger");
|
||||
LocalWeapons.Slots[2].AddWeapon ("StrifeCrossbow2");
|
||||
LocalWeapons.Slots[2].AddWeapon ("StrifeCrossbow");
|
||||
LocalWeapons.Slots[3].AddWeapon ("AssaultGun");
|
||||
LocalWeapons.Slots[4].AddWeapon ("MiniMissileLauncher");
|
||||
LocalWeapons.Slots[5].AddWeapon ("StrifeGrenadeLauncher2");
|
||||
LocalWeapons.Slots[5].AddWeapon ("StrifeGrenadeLauncher");
|
||||
LocalWeapons.Slots[6].AddWeapon ("FlameThrower");
|
||||
LocalWeapons.Slots[7].AddWeapon ("Mauler2");
|
||||
LocalWeapons.Slots[7].AddWeapon ("Mauler");
|
||||
LocalWeapons.Slots[8].AddWeapon ("Sigil");
|
||||
}
|
||||
else if (strcmp (gamename, "Chex") == 0)
|
||||
{
|
||||
LocalWeapons.Slots[1].AddWeapon ("Bootspoon");
|
||||
LocalWeapons.Slots[1].AddWeapon ("SuperBootspork");
|
||||
LocalWeapons.Slots[2].AddWeapon ("MiniZorcher");
|
||||
LocalWeapons.Slots[3].AddWeapon ("LargeZorcher");
|
||||
LocalWeapons.Slots[3].AddWeapon ("SuperLargeZorcher");
|
||||
LocalWeapons.Slots[4].AddWeapon ("RapidZorcher");
|
||||
LocalWeapons.Slots[5].AddWeapon ("ZorchPropulsor");
|
||||
LocalWeapons.Slots[6].AddWeapon ("PhasingZorcher");
|
||||
LocalWeapons.Slots[7].AddWeapon ("LAZDevice");
|
||||
}
|
||||
else // Doom
|
||||
{
|
||||
LocalWeapons.Slots[1].AddWeapon ("Fist");
|
||||
LocalWeapons.Slots[1].AddWeapon ("Chainsaw");
|
||||
LocalWeapons.Slots[2].AddWeapon ("Pistol");
|
||||
LocalWeapons.Slots[3].AddWeapon ("Shotgun");
|
||||
LocalWeapons.Slots[3].AddWeapon ("SuperShotgun");
|
||||
LocalWeapons.Slots[4].AddWeapon ("Chaingun");
|
||||
LocalWeapons.Slots[5].AddWeapon ("RocketLauncher");
|
||||
LocalWeapons.Slots[6].AddWeapon ("PlasmaRifle");
|
||||
LocalWeapons.Slots[7].AddWeapon ("BFG9000");
|
||||
}
|
||||
}
|
||||
|
||||
CCMD (whereisini)
|
||||
{
|
||||
FString path = GameConfig->GetConfigPath (false);
|
||||
|
|
|
@ -47,7 +47,6 @@ public:
|
|||
|
||||
void DoGlobalSetup ();
|
||||
void DoGameSetup (const char *gamename);
|
||||
void DoWeaponSetup (const char *gamename);
|
||||
void ArchiveGlobalData ();
|
||||
void ArchiveGameData (const char *gamename);
|
||||
void AddAutoexec (DArgs *list, const char *gamename);
|
||||
|
@ -64,7 +63,6 @@ private:
|
|||
void MigrateOldConfig ();
|
||||
void SetRavenDefaults (bool isHexen);
|
||||
void ReadCVars (DWORD flags);
|
||||
void SetupWeaponList (const char *gamename);
|
||||
|
||||
bool bMigrating;
|
||||
|
||||
|
@ -73,7 +71,6 @@ private:
|
|||
size_t sublen;
|
||||
};
|
||||
|
||||
extern FString WeaponSection;
|
||||
extern FGameConfigFile *GameConfig;
|
||||
|
||||
#endif //__GAMECONFIGFILE_H__
|
||||
|
|
|
@ -737,7 +737,7 @@ void cht_Give (player_t *player, const char *name, int amount)
|
|||
// Give the weapon only if it belongs to the current game or
|
||||
// is in a weapon slot. Unfortunately this check only works in
|
||||
// singleplayer games because the weapon slots are stored locally.
|
||||
// In multiplayer games or demors all weapons must be given because the state of
|
||||
// In multiplayer games or demos all weapons must be given because the state of
|
||||
// the weapon slots is not guaranteed to be the same when recording or playing back.
|
||||
if (multiplayer || demorecording || demoplayback ||
|
||||
type->ActorInfo->GameFilter == GAME_Any ||
|
||||
|
|
|
@ -3769,6 +3769,10 @@ APlayerPawn *P_SpawnPlayer (FMapThing *mthing, bool tempplayer)
|
|||
FBehavior::StaticStartTypedScripts (SCRIPT_Respawn, p->mo, true);
|
||||
}
|
||||
}
|
||||
if (playernum == consoleplayer)
|
||||
{
|
||||
LocalWeapons.CompleteSetup(mobj->GetClass());
|
||||
}
|
||||
return mobj;
|
||||
}
|
||||
|
||||
|
|
|
@ -1405,6 +1405,24 @@ DEFINE_CLASS_PROPERTY(yadjust, F, Weapon)
|
|||
defaults->YAdjust = i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(slotnumber, I, Weapon)
|
||||
{
|
||||
PROP_INT_PARM(i, 0);
|
||||
info->Class->Meta.SetMetaInt(AWMETA_SlotNumber, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(slotpriority, F, Weapon)
|
||||
{
|
||||
PROP_FIXED_PARM(i, 0);
|
||||
info->Class->Meta.SetMetaFixed(AWMETA_SlotPriority, i);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
@ -1823,6 +1841,30 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, hexenarmor, FFFFF, PlayerPawn)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY_PREFIX(player, weaponslot, ISsssssssssssssssssssssssssssssssssssssssssss, PlayerPawn)
|
||||
{
|
||||
PROP_INT_PARM(slot, 0);
|
||||
|
||||
if (slot < 0 || slot > 9)
|
||||
{
|
||||
I_Error("Slot must be between 0 and 9.");
|
||||
}
|
||||
else
|
||||
{
|
||||
FString weapons;
|
||||
|
||||
for(int i = 1; i < PROP_PARM_COUNT; ++i)
|
||||
{
|
||||
PROP_STRING_PARM(str, i);
|
||||
weapons << ' ' << str;
|
||||
}
|
||||
info->Class->Meta.SetMetaString(APMETA_Slot0 + slot, &weapons[1]);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
|
|
|
@ -215,6 +215,8 @@ static int STACK_ARGS TranslationMapCompare (const void *a, const void *b);
|
|||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern int PrintColors[];
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
FFont *FFont::FirstFont = NULL;
|
||||
|
@ -2057,7 +2059,7 @@ EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int bol
|
|||
const BYTE *ch = color_value;
|
||||
int newcolor = *ch++;
|
||||
|
||||
if (newcolor == '-') // Normal
|
||||
if (newcolor == '-') // Normal
|
||||
{
|
||||
newcolor = normalcolor;
|
||||
}
|
||||
|
@ -2065,6 +2067,14 @@ EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int bol
|
|||
{
|
||||
newcolor = boldcolor;
|
||||
}
|
||||
else if (newcolor == '!') // Team chat
|
||||
{
|
||||
newcolor = PrintColors[PRINT_TEAMCHAT];
|
||||
}
|
||||
else if (newcolor == '*') // Chat
|
||||
{
|
||||
newcolor = PrintColors[PRINT_CHAT];
|
||||
}
|
||||
else if (newcolor == '[') // Named
|
||||
{
|
||||
const BYTE *namestart = ch;
|
||||
|
|
|
@ -71,6 +71,9 @@ struct FBrokenLines
|
|||
#define TEXTCOLOR_NORMAL "\034-"
|
||||
#define TEXTCOLOR_BOLD "\034+"
|
||||
|
||||
#define TEXTCOLOR_CHAT "\034*"
|
||||
#define TEXTCOLOR_TEAMCHAT "\034!"
|
||||
|
||||
FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const BYTE *str);
|
||||
void V_FreeBrokenLines (FBrokenLines *lines);
|
||||
inline FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const char *str)
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
// Version stored in the ini's [LastRun] section.
|
||||
// Bump it if you made some configuration change that you want to
|
||||
// be able to migrate in FGameConfigFile::DoGlobalSetup().
|
||||
#define LASTRUNVERSION "207"
|
||||
#define LASTRUNVERSION "208"
|
||||
|
||||
// Protocol version used in demos.
|
||||
// Bump it if you change existing DEM_ commands or add new ones.
|
||||
|
|
|
@ -9,4 +9,11 @@ actor ChexPlayer : DoomPlayer
|
|||
player.startitem "Bootspoon"
|
||||
player.startitem "MiniZorchRecharge", 50
|
||||
player.damagescreencolor "60 b0 58"
|
||||
player.WeaponSlot 1, Bootspoon, SuperBootspork
|
||||
player.WeaponSlot 2, MiniZorcher
|
||||
player.WeaponSlot 3, LargeZorcher, SuperLargeZorcher
|
||||
player.WeaponSlot 4, RapidZorcher
|
||||
player.WeaponSlot 5, ZorchPropulsor
|
||||
player.WeaponSlot 6, PhasingZorcher
|
||||
player.WeaponSlot 7, LAZDevice
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@ ACTOR DoomPlayer : PlayerPawn
|
|||
Player.StartItem "Pistol"
|
||||
Player.StartItem "Fist"
|
||||
Player.StartItem "Clip", 50
|
||||
|
||||
Player.WeaponSlot 1, Fist, Chainsaw
|
||||
Player.WeaponSlot 2, Pistol
|
||||
Player.WeaponSlot 3, Shotgun, SuperShotgun
|
||||
Player.WeaponSlot 4, Chaingun
|
||||
Player.WeaponSlot 5, RocketLauncher
|
||||
Player.WeaponSlot 6, PlasmaRifle
|
||||
Player.WeaponSlot 7, BFG9000
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
@ -17,6 +17,7 @@ ACTOR DoomWeapon : Weapon
|
|||
|
||||
ACTOR Fist : Weapon
|
||||
{
|
||||
Game Doom
|
||||
Weapon.SelectionOrder 3700
|
||||
Weapon.Kickback 100
|
||||
Obituary "$OB_MPFIST"
|
||||
|
@ -52,6 +53,7 @@ ACTOR Fist : Weapon
|
|||
|
||||
ACTOR Pistol : DoomWeapon 5010
|
||||
{
|
||||
Game Doom
|
||||
Weapon.SelectionOrder 1900
|
||||
Weapon.AmmoUse 1
|
||||
Weapon.AmmoGive 20
|
||||
|
|
|
@ -11,6 +11,14 @@ ACTOR HereticPlayer : PlayerPawn
|
|||
Player.StartItem "GoldWand"
|
||||
Player.StartItem "Staff"
|
||||
Player.StartItem "GoldWandAmmo", 50
|
||||
Player.WeaponSlot 1, Staff, Gauntlets
|
||||
Player.WeaponSlot 2, GoldWand
|
||||
Player.WeaponSlot 3, Crossbow
|
||||
Player.WeaponSlot 4, Blaster
|
||||
Player.WeaponSlot 5, SkullRod
|
||||
Player.WeaponSlot 6, PhoenixRod
|
||||
Player.WeaponSlot 7, Mace
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
@ -9,6 +9,7 @@ ACTOR HereticWeapon : Weapon
|
|||
|
||||
ACTOR Staff : HereticWeapon
|
||||
{
|
||||
Game Heretic
|
||||
Weapon.SelectionOrder 3800
|
||||
+THRUGHOST
|
||||
+WIMPY_WEAPON
|
||||
|
@ -38,6 +39,7 @@ ACTOR Staff : HereticWeapon
|
|||
|
||||
ACTOR StaffPowered : Staff
|
||||
{
|
||||
Game Heretic
|
||||
Weapon.sisterweapon "Staff"
|
||||
Weapon.ReadySound "weapons/staffcrackle"
|
||||
+WEAPON.POWERED_UP
|
||||
|
@ -106,6 +108,7 @@ ACTOR StaffPuff2
|
|||
|
||||
ACTOR GoldWand : HereticWeapon
|
||||
{
|
||||
Game Heretic
|
||||
+BLOODSPLATTER
|
||||
Weapon.SelectionOrder 2000
|
||||
Weapon.AmmoGive 25
|
||||
|
@ -138,6 +141,7 @@ ACTOR GoldWand : HereticWeapon
|
|||
|
||||
ACTOR GoldWandPowered : GoldWand
|
||||
{
|
||||
Game Heretic
|
||||
+WEAPON.POWERED_UP
|
||||
Weapon.AmmoGive 0
|
||||
Weapon.SisterWeapon "GoldWand"
|
||||
|
@ -269,6 +273,7 @@ ACTOR Crossbow : HereticWeapon 2001
|
|||
|
||||
ACTOR CrossbowPowered : Crossbow
|
||||
{
|
||||
Game Heretic
|
||||
+WEAPON.POWERED_UP
|
||||
Weapon.AmmoGive 0
|
||||
Weapon.SisterWeapon "Crossbow"
|
||||
|
@ -388,7 +393,7 @@ ACTOR Gauntlets : Weapon 2005
|
|||
Weapon.YAdjust 15
|
||||
Weapon.UpSound "weapons/gauntletsactivate"
|
||||
Weapon.SisterWeapon "GauntletsPowered"
|
||||
Inventory.PickupMessage "$TxT_WPNGAUNTLETS"
|
||||
Inventory.PickupMessage "$TXT_WPNGAUNTLETS"
|
||||
|
||||
action native A_GauntletAttack (int power);
|
||||
|
||||
|
@ -420,6 +425,7 @@ ACTOR Gauntlets : Weapon 2005
|
|||
|
||||
ACTOR GauntletsPowered : Gauntlets
|
||||
{
|
||||
Game Heretic
|
||||
+POWERED_UP
|
||||
Weapon.SisterWeapon "Gauntlets"
|
||||
States
|
||||
|
@ -518,6 +524,7 @@ ACTOR Mace : HereticWeapon
|
|||
|
||||
ACTOR MacePowered : Mace
|
||||
{
|
||||
Game Heretic
|
||||
+WEAPON.POWERED_UP
|
||||
Weapon.AmmoUse 5
|
||||
Weapon.AmmoGive 0
|
||||
|
@ -704,6 +711,7 @@ ACTOR Blaster : HereticWeapon 53
|
|||
|
||||
ACTOR BlasterPowered : Blaster
|
||||
{
|
||||
Game Heretic
|
||||
+WEAPON.POWERED_UP
|
||||
Weapon.AmmoUse 5
|
||||
Weapon.AmmoGive 0
|
||||
|
@ -850,6 +858,7 @@ ACTOR SkullRod : HereticWeapon 2004
|
|||
|
||||
ACTOR SkullRodPowered : SkullRod
|
||||
{
|
||||
Game Heretic
|
||||
+WEAPON.POWERED_UP
|
||||
Weapon.AmmoUse1 5
|
||||
Weapon.AmmoGive1 0
|
||||
|
@ -1022,6 +1031,7 @@ ACTOR PhoenixRod : Weapon 2003 native
|
|||
|
||||
ACTOR PhoenixRodPowered : PhoenixRod native
|
||||
{
|
||||
Game Heretic
|
||||
+WEAPON.POWERED_UP
|
||||
Weapon.SisterWeapon "PhoenixRod"
|
||||
Weapon.AmmoGive 0
|
||||
|
|
|
@ -71,6 +71,7 @@ ACTOR WraithvergeDrop
|
|||
|
||||
ACTOR CWeapWraithverge : ClericWeapon native
|
||||
{
|
||||
Game Hexen
|
||||
Health 3
|
||||
Weapon.SelectionOrder 3000
|
||||
+WEAPON.PRIMARY_USES_BOTH
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
ACTOR CWeapMace : ClericWeapon
|
||||
{
|
||||
Game Hexen
|
||||
Weapon.SelectionOrder 3500
|
||||
Weapon.KickBack 150
|
||||
Weapon.YAdjust -8
|
||||
|
|
|
@ -22,6 +22,11 @@ ACTOR ClericPlayer : PlayerPawn
|
|||
Player.HealRadiusType "Health"
|
||||
Player.Hexenarmor 10, 10, 25, 5, 20
|
||||
Player.StartItem "CWeapMace"
|
||||
Player.WeaponSlot 1, CWeapMace
|
||||
Player.WeaponSlot 2, CWeapStaff
|
||||
Player.WeaponSlot 3, CWeapFlame
|
||||
Player.WeaponSlot 4, CWeapWraithverge
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
ACTOR FWeapFist : FighterWeapon
|
||||
{
|
||||
Game Hexen
|
||||
+BLOODSPLATTER
|
||||
Weapon.SelectionOrder 3400
|
||||
+WEAPON.MELEEWEAPON
|
||||
|
|
|
@ -22,6 +22,11 @@ ACTOR FighterPlayer : PlayerPawn
|
|||
Player.StartItem "FWeapFist"
|
||||
Player.ForwardMove 1.08, 1.2
|
||||
Player.SideMove 1.125, 1.475
|
||||
Player.WeaponSlot 1, FWeapFist
|
||||
Player.WeaponSlot 2, FWeapAxe
|
||||
Player.WeaponSlot 3, FWeapHammer
|
||||
Player.WeaponSlot 4, FWeapQuietus
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
@ -71,6 +71,7 @@ ACTOR QuietusDrop
|
|||
|
||||
ACTOR FWeapQuietus : FighterWeapon
|
||||
{
|
||||
Game Hexen
|
||||
Health 3
|
||||
Weapon.SelectionOrder 2900
|
||||
+WEAPON.PRIMARY_USES_BOTH
|
||||
|
|
|
@ -24,6 +24,11 @@ ACTOR MagePlayer : PlayerPawn
|
|||
Player.StartItem "MWeapWand"
|
||||
Player.ForwardMove 0.88, 0.92
|
||||
Player.SideMove 0.875, 0.925
|
||||
Player.WeaponSlot 1, MWeapWand
|
||||
Player.WeaponSlot 2, MWeapFrost
|
||||
Player.WeaponSlot 3, MWeapLightning
|
||||
Player.WeaponSlot 4, MWeapBloodscourge
|
||||
|
||||
States
|
||||
{
|
||||
Spawn:
|
||||
|
|
|
@ -71,6 +71,7 @@ ACTOR BloodscourgeDrop
|
|||
|
||||
ACTOR MWeapBloodscourge : MageWeapon native
|
||||
{
|
||||
Game Hexen
|
||||
Health 3
|
||||
Weapon.SelectionOrder 3100
|
||||
Weapon.AmmoUse1 15
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
|
||||
ACTOR MWeapWand : MageWeapon
|
||||
{
|
||||
Game Hexen
|
||||
Weapon.SelectionOrder 3600
|
||||
Weapon.KickBack 0
|
||||
Weapon.YAdjust 9
|
||||
|
||||
States
|
||||
{
|
||||
Select:
|
||||
|
|
|
@ -12,6 +12,14 @@ ACTOR StrifePlayer : PlayerPawn
|
|||
Player.ColorRange 128, 143
|
||||
Player.DisplayName "Rebel"
|
||||
Player.StartItem "PunchDagger"
|
||||
Player.WeaponSlot 1, PunchDagger
|
||||
Player.WeaponSlot 2, StrifeCrossbow2, StrifeCrossbow
|
||||
Player.WeaponSlot 3, AssaultGun
|
||||
Player.WeaponSlot 4, MiniMissileLauncher
|
||||
Player.WeaponSlot 5, StrifeGrenadeLauncher2, StrifeGrenadeLauncher
|
||||
Player.WeaponSlot 6, FlameThrower
|
||||
Player.WeaponSlot 7, Mauler2, Mauler
|
||||
Player.WeaponSlot 8, Sigil
|
||||
|
||||
action native A_ItBurnsItBurns();
|
||||
action native A_CrispyPlayer();
|
||||
|
|
|
@ -45,6 +45,7 @@ ACTOR StrifeSpark : StrifePuff
|
|||
|
||||
ACTOR PunchDagger : StrifeWeapon
|
||||
{
|
||||
Game Strife
|
||||
Weapon.SelectionOrder 3900
|
||||
+WEAPON.NOALERT
|
||||
|
||||
|
@ -198,11 +199,13 @@ ACTOR StrifeCrossbow : StrifeWeapon 2001
|
|||
|
||||
ACTOR StrifeCrossbow2 : StrifeCrossbow
|
||||
{
|
||||
Game Strife
|
||||
Weapon.SelectionOrder 2700
|
||||
Weapon.AmmoUse1 1
|
||||
Weapon.AmmoGive1 0
|
||||
Weapon.AmmoType1 "PoisonBolts"
|
||||
Weapon.SisterWeapon "StrifeCrossbow"
|
||||
|
||||
States
|
||||
{
|
||||
Ready:
|
||||
|
@ -362,6 +365,7 @@ ACTOR MiniMissilePuff : StrifePuff
|
|||
|
||||
ACTOR MiniMissile
|
||||
{
|
||||
Game Strife
|
||||
ConversationID 99,-1,-1
|
||||
Speed 20
|
||||
Radius 10
|
||||
|
@ -515,6 +519,7 @@ ACTOR Mauler : StrifeWeapon 2004
|
|||
|
||||
ACTOR Mauler2 : Mauler
|
||||
{
|
||||
Game Strife
|
||||
Weapon.SelectionOrder 3300
|
||||
Weapon.AmmoUse1 30
|
||||
Weapon.AmmoGive1 0
|
||||
|
@ -626,6 +631,7 @@ ACTOR MaulerTorpedoWave
|
|||
|
||||
ACTOR HEGrenade
|
||||
{
|
||||
Game Strife
|
||||
ConversationID 106,-1,-1
|
||||
Speed 15
|
||||
Radius 13
|
||||
|
@ -663,6 +669,7 @@ ACTOR HEGrenade
|
|||
|
||||
ACTOR PhosphorousGrenade
|
||||
{
|
||||
Game Strife
|
||||
ConversationID 107,-1,-1
|
||||
Speed 15
|
||||
Radius 13
|
||||
|
@ -782,6 +789,7 @@ ACTOR StrifeGrenadeLauncher : StrifeWeapon 154
|
|||
|
||||
ACTOR StrifeGrenadeLauncher2 : StrifeGrenadeLauncher
|
||||
{
|
||||
Game Strife
|
||||
Weapon.SelectionOrder 3200
|
||||
Weapon.AmmoUse1 1
|
||||
Weapon.AmmoGive1 0
|
||||
|
|
Loading…
Reference in a new issue