[For a long time]Strife's peasant is completely harmless

Forum rules
Please don't bump threads here if you have a problem - it will often be forgotten about if you do. Instead, make a new thread here.

Post a reply

Smilies
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :geek: :ugeek: :!: :?: :idea: :arrow: :| :mrgreen: :3: :wub: >:( :blergh:
View more smilies

BBCode is OFF
Smilies are ON

Topic review
   

Expand view Topic review: [For a long time]Strife's peasant is completely harmless

Re: [For a long time]Strife's peasant is completely harmless

by Graf Zahl » Fri Oct 24, 2014 5:15 pm

Ok, sounds reasonable.

Re: [For a long time]Strife's peasant is completely harmless

by Fishytza » Fri Oct 24, 2014 5:02 pm

Apologies for the long posts, I'll try to make it simple.

In order to make the peasant's punch damage the player I respectfully suggest removing FRIENDLY and adding NEVERTARGET. Is this really gonna cause problems? This is the simplest and sanest way to go about this.

Why remove FRIENDLY? Because it prevents two internal functions from acquiring the player as a target (OkayToSwitchTarget) and damaging them (CheckMeleeRange).
[EDIT]Removed links.[/EDIT]

Why add NEVERTARGET? So that friendly monsters don't waste their time killing peasants when they should be killing something else.

How does this relate to vanilla?
1) Peasants in vanilla Strife are by default not friendly.

2) Friendlies in vanilla Strife only attack peasants if you shoot at the peasants' general direction.

In ZDoom, (assuming FRIENDLY has been swapped with NEVERTARGET) a friendly would only ever attack a peasant when said peasant damages the friendly's FriendPlayer. While it's not the same thing, it's a close enough substitute IMO. Otherwise you'd have to change the behavior of friendly monsters and I'm sure that would be quite undesirable.

Re: [For a long time]Strife's peasant is completely harmless

by Graf Zahl » Fri Oct 24, 2014 3:25 pm

It's hard to extract something from your lengthy posts. Yes, I see that something is wrong - but I absolutely don't get what should be done instead. You describe a lot of options. Which one is closest or equal to vanilla Strife. That's the only reference here, all other considerations are not relevant.

Re: [For a long time]Strife's peasant is completely harmless

by Fishytza » Mon Oct 20, 2014 5:39 am

Gonna make this quick, got a busy day today.

Here's a test map that you can run with vanilla (via DOSBox) or choco Strife if you wish:
[EDIT] Updated test map to include a friendly red acolyte and a teleport beacon. The beacon rebels will sometimes attack the red acolyte too. Weird.[/EDIT]

[EDIT2]Test map removed.[/EDIT2]

NOTE: Make sure that, if you're gonna use vanilla, to update your strife1.exe to the latest version (1.31)

The green floors are covered with sound blocking lines, meaning you have to get across them to do the following tests.

Go in the right room with the 2 peasants. The red one is marked as friendly (ally in DB2). Punch either one of them and they should punch you back. You should receive damage from the punch.

Now select the assault gun and fire at a wall, the tan (non-red) peasant should start walking around constantly. Punch them again. Interestingly, the red one will behave like in ZDoom, he won't turn towards you and his punch won't damage you. The tan one will still face and damage you.

Now to see how friendly rebels in vanilla behave.
Restart the map, grab everything and go to the left room. If you shoot your gun at a wall away from anything, the acolyte will attack, but the rebel usually won't do anything. If you shoot the acolyte, the rebel will attack the acolyte. If you shoot the beggar, the rebel will attack the beggar. if you shoot the peasant, guess what, the rebel will attack the peasant.

Speaking of the beggar, his DECORATE code shows he has the same flags as the peasant sans FRIENDLY and FLOORCLIP. If you were to run these tests in ZDoom, the rebel would attack the acolyte *and* the beggar but ignore the peasant.

EDIT: The point of testing the behavior of "vanilla friendlies" is to show two things: 1) Unless it's an "ally", your allies/friendlies will attack whatever you shoot at, this includes peasants. 2) Based on 1) I think we can safely conclude that peasants were never supposed to be friendlies in the first place.

Of course this presents a problem, if we remove FRIENDLY then the peasants will get attacked automatically (in ZDoom) without the need for you to shoot at their general direction (unlike vanilla Strife).

Adding the NEVERTARGET flag would fix that issue since it doesn't defy Thing_Hate and they'll still get attacked if they damage the player.
Reason why that happens is because the last thing that hurts a player will be stored in the "attacker" pointer and if that player is a friendly's FriendPlayer then the friendly will attack the "attacker" regardless of NEVERTARGET as shown in p_enemy.cpp:

Code: Select all

	if (actor->flags & MF_FRIENDLY && actor->target == NULL) //L2236
	{
   ....
   ....
		if (player->attacker && player->attacker->health > 0 && player->attacker->flags & MF_SHOOTABLE && pr_newchasedir() < 80) //L2256
		{
			if (!(player->attacker->flags & MF_FRIENDLY) ||
				(deathmatch && actor->FriendPlayer != 0 && player->attacker->FriendPlayer != 0 &&
				actor->FriendPlayer != player->attacker->FriendPlayer))
			{
				actor->target = player->attacker;
			} 
		}
}
This is fine, though, since it's closer to vanilla (where your allies attack whatever non-ally you shoot at, this includes peasants).

If removing FRIENDLY still seems like an issue then I would like to suggest a small (and IMO hacky) adjustment to OkayToSwitchTarget() and CheckMeleeRange():

Code: Select all

	if (IsFriend(x) && !(GetDefault()->flags & MF_JUSTHIT)) //Peasants have this flag by default; allow them to retaliate against abusive players
Where x is "pl" for CheckMeleeRange() and "other" for OkayToSwitchTarget()

I know I'm putting way too much effort into this "non-issue" as some might call it, but hey, a bug is a bug, right. :P
Sorry if I seem to be repeating myself, I just want to be as clear as possible.

Re: [For a long time]Strife's peasant is completely harmless

by Fishytza » Mon Oct 20, 2014 3:37 am

Aside from FRIENDLY preventing A_CustomMeleeAttack from doing any damage, one other (IMO Insignificant) difference is how A_Wander behaves. Friendly monsters, unlike non-friendlies, have a small tendency to follow around a player rather than truly randomly walking around when calling A_Wander. (This is because of P_RandomChaseDir which is called by A_Wander).

Another is that the peasants would wander around constantly when you "make noise" because A_Look2 doesn't clear the LastHeard pointer and because of that it would always go to the See state.

EDIT: I'm gonna try and get DOSBox and STRIFE1.exe ready and maybe make a test map to see what is what.

Re: [For a long time]Strife's peasant is completely harmless

by Enjay » Mon Oct 20, 2014 2:05 am

Certainly in Vanilla Strife, the peasants attack you (one punch) and the punch does damage. Other than that, they seem to behave much like the ZDoom ones. Looking at the DECORATE of the peasants, they never use A_Chase (they use A_Wander instead) so they do not make a "can I attack my target" check in their "See" state sequence. The only way I can see of them going into their "Melee" sequence is via their "Pain" sequence (the "Pain" sequence finishes with "goto Melee"). So, unless the "FRIENDLY" flag confers some other required ability or property to the peasants, my guess is that it could be removed without making the peasamts behave in an unwanted manner.

Re: [For a long time]Strife's peasant is completely harmless

by Fishytza » Sun Oct 19, 2014 5:23 pm

Are you telling me that them not inflicting any damage even though they should considering you're within their melee range is normal?

If you're talking about them not being 'friendly' well the closest we can look at code-wise would be chocolate strife, right?

According to choco strife's info.c, starting at L1880:

Code: Select all

    {       /*MT_PEASANT2_A*/
        3004,       //doomednum
        S_PEAS_00,      //spawnstate
        31,     //spawnhealth
        S_PEAS_01,      //seestate
        sfx_rebact,     //seesound
        8,      //reactiontime
        sfx_meatht,     //attacksound
        S_PEAS_12,      //painstate
        200,        //painchance
        sfx_pespna,     //painsound
        S_PEAS_09,      //meleestate
        S_NULL,     //missilestate
        S_PEAS_14,      //crashstate
        S_PEAS_17,      //deathstate
        S_GIBS_00,      //xdeathstate
        sfx_psdtha,     //deathsound
        4,      //speed
        20*FRACUNIT,        //radius
        56*FRACUNIT,        //height
        100,        //mass
        0,      //damage
        sfx_rebact,     //activesound
        MF_SOLID|MF_SHOOTABLE|MF_JUSTHIT|MF_COUNTKILL,      //flags
        NULL,       //namepointer
    },
Choco's version of the FRIENDLY flag is MF_ALLY, and the only things that have that set by default are the MT_REBEL* types and MT_PLAYER.

It's been a while since I ran Strife in DOSBox and I don't have it installed at the moment. I even gave Chocolate Strife I try some time ago and things were pretty similiar when compared to DOSBox as far as I remember. That is, a peasant's punch *would* hurt you if you were close enough and rebels never attack a peasant unless you fired your gun at one. Granted the rebels' behavior in vanilla and choco Strife isn't exactly the same as ZDoom's friendly monsters.

I guess I have to give DOSBox another test run later.
(I could also use some much needed sleep)

Re: [For a long time]Strife's peasant is completely harmless

by wildweasel » Sun Oct 19, 2014 4:00 pm

Is this consistent with the peasants' behavior in vanilla Strife, though?

[For a long time]Strife's peasant is completely harmless

by Fishytza » Sun Oct 19, 2014 10:08 am

Just walk within a peasant's melee distance and attack him with the dagger. He'll try to punch you, but you won't receive any damage.

Obvious culprit here is the fact that peasants are friendlies by default (they have the FRIENDLY flag).

First of all, CheckMeleeRange(), which is called by A_CustomMeleeAttack, does the following (p_enemy.cpp, L252):

Code: Select all

	if (IsFriend(pl))
		return false;
Even if we get that out of the way, OkayToSwitchTarget() would still object (p_interaction.cpp, L1541):

Code: Select all

	if (IsFriend (other))
	{ // [RH] Friendlies don't target other friendlies
		return false;
	}
The only reason the peasant ever acquires the player as a target (as evidenced by A_FaceTarget making him turn to face you) is because of P_DaggerAlert() called by A_JabDagger, but only if his LastHeard pointer is NULL meaning that he'll only target you if haven't made any noise at all.
a_strifeweapons.cpp:

Code: Select all

void P_DaggerAlert (AActor *target, AActor *emitter)
{
   ....
	if (emitter->LastHeard != NULL) //L45
		return;
   ....
   ....
	emitter->target = target; //L55
Frankly, the simplest and least troublesome way to fix this would be to replace FRIENDLY with the NEVERTARGET flag. That way friendlies (specifically rebels) won't actively kill them (they were never supposed to) and the peasants will retaliate whenever you attack them (provided they survive).

Unless I'm missing something here, there should be no consequence giving them NEVERTARGET, since Thing_Hate would still work as expected (judging from a few quick tests).

Top