This commit is contained in:
Christoph Oelckers 2015-12-02 09:31:27 +01:00
commit 41f91148a1
19 changed files with 117 additions and 26 deletions

View file

@ -237,6 +237,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
scalex = <float>; // Vertical scaling on thing. Default = 0 (ignored).
scaley = <float>; // Horizontal scaling on thing. Default = 0 (ignored).
scale = <float>; // Vertical and horizontal scaling on thing. Default = 0 (ignored).
floatbobphase = <int>; // Sets the thing's floatbobphase. Valid phase values are 0-63. Default = -1 (use actor class default).
* Note about arg0str

View file

@ -432,7 +432,7 @@ WORD FDecalLib::GetDecalID (FScanner &sc)
unsigned long num = strtoul (sc.String, NULL, 10);
if (num < 1 || num > 65535)
{
sc.MustGetStringName ("Decal ID must be between 1 and 65535");
sc.ScriptError ("Decal ID must be between 1 and 65535");
}
return (WORD)num;
}
@ -603,16 +603,18 @@ void FDecalLib::ParseGenerator (FScanner &sc)
{
const PClass *type;
FDecalBase *decal;
AActor *actor;
bool optional = false;
// Get name of generator (actor)
sc.MustGetString ();
optional = sc.Compare("optional");
if (optional) sc.MustGetString();
type = PClass::FindClass (sc.String);
if (type == NULL || type->ActorInfo == NULL)
{
sc.ScriptError ("%s is not an actor.", sc.String);
if (!optional) sc.ScriptError ("%s is not an actor.", sc.String);
}
actor = (AActor *)type->Defaults;
// Get name of generated decal
sc.MustGetString ();
@ -625,14 +627,17 @@ void FDecalLib::ParseGenerator (FScanner &sc)
decal = ScanTreeForName (sc.String, Root);
if (decal == NULL)
{
sc.ScriptError ("%s has not been defined.", sc.String);
if (!optional) sc.ScriptError ("%s has not been defined.", sc.String);
}
}
actor->DecalGenerator = decal;
if (decal != NULL)
if (type != NULL)
{
decal->Users.Push (type);
AActor *actor = (AActor *)type->Defaults;
actor->DecalGenerator = decal;
if (decal != NULL)
{
decal->Users.Push(type);
}
}
}

View file

@ -365,6 +365,7 @@ struct FMapThing
short pitch;
short roll;
DWORD RenderStyle;
int FloatbobPhase;
};

View file

@ -563,8 +563,10 @@ enum ESkillProperty
SKILLP_FriendlyHealth,
SKILLP_NoPain,
SKILLP_ArmorFactor,
SKILLP_HealthFactor,
SKILLP_EasyKey,
SKILLP_SlowMonsters,
SKILLP_Infight,
};
int G_SkillProperty(ESkillProperty prop);
const char * G_SkillName();
@ -602,7 +604,9 @@ struct FSkillInfo
fixed_t MonsterHealth;
fixed_t FriendlyHealth;
bool NoPain;
int Infighting;
fixed_t ArmorFactor;
fixed_t HealthFactor;
FSkillInfo() {}
FSkillInfo(const FSkillInfo &other)

View file

@ -236,10 +236,12 @@ bool P_GiveBody (AActor *actor, int num, int max)
return true;
}
}
else
else if (num > 0)
{
if (player->health < max)
{
num = FixedMul(num, G_SkillProperty(SKILLP_HealthFactor));
if (num < 1) num = 1;
player->health += num;
if (player->health > max)
{

View file

@ -83,6 +83,8 @@ void FMapInfoParser::ParseSkill ()
skill.FriendlyHealth = FRACUNIT;
skill.NoPain = false;
skill.ArmorFactor = FRACUNIT;
skill.Infighting = 0;
skill.HealthFactor = FRACUNIT;
sc.MustGetString();
skill.Name = sc.String;
@ -266,6 +268,20 @@ void FMapInfoParser::ParseSkill ()
sc.MustGetFloat();
skill.ArmorFactor = FLOAT2FIXED(sc.Float);
}
else if (sc.Compare("HealthFactor"))
{
ParseAssign();
sc.MustGetFloat();
skill.HealthFactor = FLOAT2FIXED(sc.Float);
}
else if (sc.Compare("NoInfighting"))
{
skill.Infighting = LEVEL2_NOINFIGHTING;
}
else if (sc.Compare("TotalInfighting"))
{
skill.Infighting = LEVEL2_TOTALINFIGHTING;
}
else if (sc.Compare("DefaultSkill"))
{
if (DefaultSkill >= 0)
@ -384,6 +400,17 @@ int G_SkillProperty(ESkillProperty prop)
case SKILLP_ArmorFactor:
return AllSkills[gameskill].ArmorFactor;
case SKILLP_HealthFactor:
return AllSkills[gameskill].HealthFactor;
case SKILLP_Infight:
// This property also needs to consider the level flags for the same info.
if (level.flags2 & LEVEL2_TOTALINFIGHTING) return 1;
if (level.flags2 & LEVEL2_NOINFIGHTING) return -1;
if (AllSkills[gameskill].Infighting == LEVEL2_TOTALINFIGHTING) return 1;
if (AllSkills[gameskill].Infighting == LEVEL2_NOINFIGHTING) return -1;
return infighting;
}
}
return 0;
@ -463,7 +490,9 @@ FSkillInfo &FSkillInfo::operator=(const FSkillInfo &other)
MonsterHealth = other.MonsterHealth;
FriendlyHealth = other.FriendlyHealth;
NoPain = other.NoPain;
Infighting = other.Infighting;
ArmorFactor = other.ArmorFactor;
HealthFactor = other.HealthFactor;
return *this;
}

View file

@ -1045,6 +1045,19 @@ public:
return text;
}
int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected)
{
if (mEntering)
{
// reposition the text so that the cursor is visible when in entering mode.
FString text = Represent();
int tlen = SmallFont->StringWidth(text) * CleanXfac_1;
int newindent = screen->GetWidth() - tlen - CURSORSPACE;
if (newindent < indent) indent = newindent;
}
return FOptionMenuFieldBase::Draw(desc, y, indent, selected);
}
bool MenuEvent ( int mkey, bool fromcontroller )
{
if ( mkey == MKEY_Enter )

View file

@ -396,6 +396,7 @@ xx(Roll)
xx(Scale)
xx(ScaleX)
xx(ScaleY)
xx(Floatbobphase)
xx(Blocking)
xx(Blockmonsters)

View file

@ -707,6 +707,7 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites,
mapthings[count].RenderStyle = STYLE_Count;
mapthings[count].alpha = -1;
mapthings[count].health = -1;
mapthings[count].FloatbobPhase = -1;
if (xsprites != NULL && sprites[i].lotag == 710)
{ // Blood ambient sound

View file

@ -1639,10 +1639,8 @@ bool AActor::OkayToSwitchTarget (AActor *other)
int infight;
if (flags5 & MF5_NOINFIGHTING) infight=-1;
else if (level.flags2 & LEVEL2_TOTALINFIGHTING) infight=1;
else if (level.flags2 & LEVEL2_NOINFIGHTING) infight=-1;
else infight = infighting;
else infight = G_SkillProperty(SKILLP_Infight);
if (infight < 0 && other->player == NULL && !IsHostile (other))
{
return false; // infighting off: Non-friendlies don't target other non-friendlies

View file

@ -1600,6 +1600,11 @@ FUNC(LS_Thing_Move) // [BC]
return P_Thing_Move (arg0, it, arg1, arg2 ? false : true);
}
enum
{
TRANSLATION_ICE = 0x100007
};
FUNC(LS_Thing_SetTranslation)
// Thing_SetTranslation (tid, range)
{
@ -1616,6 +1621,10 @@ FUNC(LS_Thing_SetTranslation)
{
range = TRANSLATION(TRANSLATION_LevelScripted, (arg1-1));
}
else if (arg1 == TRANSLATION_ICE)
{
range = TRANSLATION(TRANSLATION_Standard, 7);
}
else
{
range = 0;
@ -2991,7 +3000,7 @@ FUNC(LS_SendToCommunicator)
FString msg;
msg.Format("TXT_COMM%d", arg2);
const char *str = GStrings[msg];
if (msg != NULL)
if (str != NULL)
{
Printf (PRINT_CHAT, "%s\n", str);
}

View file

@ -938,10 +938,7 @@ static bool CanAttackHurt(AActor *victim, AActor *shooter)
// to harm / be harmed by anything.
if (!victim->player && !shooter->player)
{
int infight;
if (level.flags2 & LEVEL2_TOTALINFIGHTING) infight = 1;
else if (level.flags2 & LEVEL2_NOINFIGHTING) infight = -1;
else infight = infighting;
int infight = G_SkillProperty(SKILLP_Infight);
if (infight < 0)
{

View file

@ -4917,6 +4917,7 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position)
mobj->SpawnPoint[2] = mthing->z;
mobj->SpawnAngle = mthing->angle;
mobj->SpawnFlags = mthing->flags;
if (mthing->FloatbobPhase >= 0 && mthing->FloatbobPhase < 64) mobj->FloatBobPhase = mthing->FloatbobPhase;
if (mthing->gravity < 0) mobj->gravity = -mthing->gravity;
else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity);
else mobj->flags &= ~MF_NOGRAVITY;

View file

@ -1758,6 +1758,7 @@ void P_LoadThings (MapData * map)
mti[i].RenderStyle = STYLE_Count;
mti[i].alpha = -1;
mti[i].health = 1;
mti[i].FloatbobPhase = -1;
flags &= ~MTF_SKILLMASK;
mti[i].flags = (short)((flags & 0xf) | 0x7e0);
if (gameinfo.gametype == GAME_Strife)
@ -1842,6 +1843,7 @@ void P_LoadThings2 (MapData * map)
mti[i].RenderStyle = STYLE_Count;
mti[i].alpha = -1;
mti[i].health = 1;
mti[i].FloatbobPhase = -1;
}
delete[] mtp;
}

View file

@ -474,6 +474,7 @@ public:
th->RenderStyle = STYLE_Count;
th->alpha = -1;
th->health = 1;
th->FloatbobPhase = -1;
sc.MustGetToken('{');
while (!sc.CheckToken('}'))
{
@ -631,6 +632,11 @@ public:
Flag(th->flags, MTF_SECRET, key);
break;
case NAME_Floatbobphase:
CHECK_N(Zd | Zdt)
th->FloatbobPhase = CheckInt(key);
break;
case NAME_Renderstyle:
{
FName style = CheckString(key);

View file

@ -713,11 +713,11 @@ BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
if ( hRT )
{
// Must wait process to terminate to guarantee that it has exited...
WaitForSingleObject(hProcess, INFINITE);
// Must wait for process to terminate to guarantee that it has exited...
DWORD res = WaitForSingleObject(hProcess, 1000);
CloseHandle(hRT);
bSuccess = TRUE;
bSuccess = (res == WAIT_OBJECT_0);
dwErr = WAIT_TIMEOUT;
}
if ( !bSuccess )

View file

@ -1414,6 +1414,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
ACTION_PARAM_FIXED(LifeSteal, 5);
ACTION_PARAM_INT(lifestealmax, 6);
ACTION_PARAM_CLASS(armorbonustype, 7);
ACTION_PARAM_SOUND(MeleeSound, 8);
ACTION_PARAM_SOUND(MissSound, 9);
if (!self->player) return;
@ -1443,7 +1445,11 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
P_LineAttack (self, angle, Range, pitch, Damage, NAME_Melee, PuffType, puffFlags, &linetarget, &actualdamage);
if (linetarget)
if (!linetarget)
{
if (MissSound) S_Sound(self, CHAN_WEAPON, MissSound, 1, ATTN_NORM);
}
else
{
if (LifeSteal && !(linetarget->flags5 & MF5_DONTDRAIN))
{
@ -1474,7 +1480,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CustomPunch)
if (weapon != NULL)
{
S_Sound (self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
if (MeleeSound) S_Sound(self, CHAN_WEAPON, MeleeSound, 1, ATTN_NORM);
else S_Sound (self, CHAN_WEAPON, weapon->AttackSound, 1, ATTN_NORM);
}
if (!(flags & CPF_NOTURN))

View file

@ -8,7 +8,7 @@ ACTOR Inventory native
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG"
action native A_JumpIfNoAmmo(state label);
action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus");
action native A_CustomPunch(int damage, bool norandom = false, int flags = CPF_USEAMMO, class<Actor> pufftype = "BulletPuff", float range = 0, float lifesteal = 0, int lifestealmax = 0, class<BasicArmorBonus> armorbonustype = "ArmorBonus", sound MeleeSound = "", sound MissSound = "");
action native A_FireBullets(float spread_xy, float spread_z, int numbullets, int damageperbullet, class<Actor> pufftype = "BulletPuff", int flags = 1, float range = 0);
action native A_FireCustomMissile(class<Actor> missiletype, float angle = 0, bool useammo = true, int spawnofs_xy = 0, float spawnheight = 0, int flags = 0, float pitch = 0);
action native A_RailAttack(int damage, int spawnofs_xy = 0, int useammo = true, color color1 = "", color color2 = "", int flags = 0, float maxdiff = 0, class<Actor> pufftype = "BulletPuff", float spread_xy = 0, float spread_z = 0, float range = 0, int duration = 0, float sparsity = 1.0, float driftspeed = 1.0, class<Actor> spawnclass = "none", float spawnofs_z = 0, int spiraloffset = 270);

View file

@ -1602,10 +1602,24 @@ OptionMenu AdvSoundOptions
Option "OPL Emulator Core", "opl_core", "OplCores"
StaticText " "
StaticText "GUS Emulation", 1
TextField "GUS config file", "midi_config"
Slider "MIDI voices", "midi_voices", 16, 256, 4, 0
Option "Emulate TiMidity", "midi_timiditylike", "OnOff"
Option "Read DMXGUS lumps", "midi_dmxgus", "OnOff"
Option "GUS memory size", "gus_memsize", "GusMemory"
StaticText " "
StaticText "FluidSynth", 1
TextField "Patch set", "fluid_patchset"
Slider "Gain", "fluid_gain", 0, 10, 0.5, 1
Option "Reverb", "fluid_reverb", "OnOff"
Slider "MIDI voices", "fluid_voices", 16, 4096, 16, 1
// Leaving out the more advanced stuff for now.
StaticText " "
StaticText "Timidity++", 1
TextField "Path for executable", "timidity_exe"
Option "Reverb", "timidity_reverb", "OnOff"
Option "Chorus", "timidity_chorus", "OnOff"
Slider "Relative volume", "timidity_mastervolume", 0, 4, 0.2, 1
}
/*=======================================