HELP - Emulating Hexen Melee

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
Locked
User avatar
Darlos
Posts: 133
Joined: Mon Apr 09, 2007 1:41 am
Location: Durham, NC
Contact:

HELP - Emulating Hexen Melee

Post by Darlos »

So, I'm getting back into modding because I wanted to mess around with the weapons and classes in Hexen. I figured I'd start with the Fighter's humble fists, by dividing the "jabs" and the third "strong" punch into primary and secondary fire, respectively. In doing this, I want to emulate the actual collision detection process described here, but quite frankly I'm a little lost. Using DECORATE or ACS or whatever, I'm not sure what the best way is to re-create the whole "sweep left and right" scanning for finding a victim. The best I've got so far is using a bunch of incremental A_CheckLOF in DECORATE, but that seems a bit awkward, since its not like I can retain which increment or potential victim triggered a jump.

So, any of you gurus have somewhere you can point me? If I'm going the ACS route, I'd probably just get all the nearby hittable things and then do math until I find the best candidate for punching. But I don't even know the best way to just get a list of said hittable things in the map to search through. Or if that would even be an efficient solution in the first place.
User avatar
Darlos
Posts: 133
Joined: Mon Apr 09, 2007 1:41 am
Location: Durham, NC
Contact:

Re: HELP - Emulating Hexen Melee

Post by Darlos »

Okay so I've been messing with this, and here's what I have so far.

Here's the DECORATE stuff:

Code: Select all

//******
// FIST
//******

Actor DHPunchPuff
{
  +NOBLOCKMAP
  +NOGRAVITY
  +PUFFONACTORS
  RenderStyle Translucent
  Alpha 0.6
  SeeSound "FighterPunchHitThing"
  AttackSound "FighterPunchHitWall"
  VSpeed 1
  States
  {
  Spawn:
    FHFX STUVW 4
    Stop
  }
}

Actor DHFWeapFist : FWeapFist replaces FWeapFist
{
  Weapon.KickBack 0

States
  {
  Select:
    FPCH A 1 A_Raise
    Loop
  Deselect:
    FPCH A 1 A_Lower
    Loop
  Ready:
    FPCH A 1 A_WeaponReady
    Loop
  Fire:
    FJAB A 5 Offset(0, 40) 
    FJAB B 4 Offset(0, 40) A_PlaySound("FighterPunchMiss", 1)
		FJAB C 0 Offset(0, 40) A_SetUserVar("user_meleeangle", 0)
	FireCheckLeft:
    FJAB C 0 Offset(0, 40) A_CheckLOF("FireResult", CLOFF_JUMPENEMY | CLOFF_JUMPFRIEND | CLOFF_JUMPOBJECT | CLOFF_JUMPNONHOSTILE | CLOFF_ALLOWNULL, 128, 0, ACS_NamedExecuteWithResult("GetMeleeAngle"), 0, 0, 0, AAPTR_NULL)
		FJAB C 0 Offset(0, 40) A_SetUserVar("user_meleeangle", ACS_NamedExecuteWithResult("GetMeleeAngle") - 1)
		FJAB C 0 Offset(0, 40) A_JumpIf(ACS_NamedExecuteWithResult("GetMeleeAngle") >= -45, "FireCheckLeft")
		FJAB C 0 Offset(0, 40) A_SetUserVar("user_meleeangle", 1)
	FireCheckRight:
    FJAB C 0 Offset(0, 40) A_CheckLOF("FireResult", CLOFF_JUMPENEMY | CLOFF_JUMPFRIEND | CLOFF_JUMPOBJECT | CLOFF_JUMPNONHOSTILE | CLOFF_ALLOWNULL, 128, 0, ACS_NamedExecuteWithResult("GetMeleeAngle"), 0, 0, 0, AAPTR_NULL)
		FJAB C 0 Offset(0, 40) A_SetUserVar("user_meleeangle", ACS_NamedExecuteWithResult("GetMeleeAngle") + 1)
		FJAB C 0 Offset(0, 40) A_JumpIf(ACS_NamedExecuteWithResult("GetMeleeAngle") <= 45, "FireCheckRight")
		FJAB C 0 Offset(0, 40) A_SetUserVar("user_meleeangle", 0)
	FireResult:
	  FJAB C 4 Offset(0, 40) A_FireBullets(ACS_NamedExecuteWithResult("GetMeleeAngle"), 0, 1, 40+random(0, 15), "DHPunchPuff", FBF_EXPLICITANGLE | FBF_NOFLASH | FBF_NORANDOM, 128)
    FJAB B 4 Offset(0, 40) A_LogInt(ACS_NamedExecuteWithResult("GetMeleeAngle"))
    FJAB A 5 Offset(0, 40) A_ReFire
	  Goto Ready
  AltFire:
    FPCH B 5 Offset(50, 40)
    FPCH C 4 Offset(50, 40) 
    FPCH DE 4 Offset(5, 40)
    FPCH E 1 Offset(15, 50)
    FPCH E 1 Offset(25, 60)
    FPCH E 1 Offset(35, 70)
    FPCH E 1 Offset(45, 80)
    FPCH E 1 Offset(55, 90)
    FPCH E 1 Offset(65, 90)
    FPCH E 10 Offset(0, 150)
    Goto Ready
	AltFireHit:
		Goto Ready
	}
}
GetMeleeAngle is pretty straightforward:

Code: Select all

#library "DH_TOOLS"
#include "zcommon.acs"

Script "GetMeleeAngle" (void)
{
  int meleeAngle = 0;
  meleeAngle = GetUserVariable(0, "user_meleeangle");
	SetResultValue(meleeAngle);
}
"user_meleeangle" is set on the player actor.

Now, the problem is, the A_CheckLOF seems to be detecting things fine, as the logging seems to suggest. However, the resulting bullet doesn't reliably hit anything that isn't at an angle of 0. So an enemy that isn't directly in front of the player can be detected, but often won't be hit. Strangely, replacing the FireBullets with a similar RailAttack like this:

Code: Select all

FJAB C 4 Offset(0, 40) A_RailAttack(40+random(0, 15), 0, 0, "ff ff a0", "ff ff a0", RGF_EXPLICITANGLE, 0, "DHPunchPuff", ACS_NamedExecuteWithResult("GetMeleeAngle"), 0, 128)
Seems to hit more or less reliably? But I might be imagining that. At any rate, the attacks don't seem to be hitting as reliably as the vanilla fist does, at the odder angles.

Is there something I'm not understanding in regards to how angles and ranges are handled between different "ray casting" functions? Or should I expect them all to behave identically?
Attachments
DarkHexen.zip
(12.09 KiB) Downloaded 17 times
Locked

Return to “Editing (Archive)”