How to save and restore a Pawn's AttitudeToPlayer?

Discussions about Coding and Scripting
User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

How to save and restore a Pawn's AttitudeToPlayer?

Post by Barbie » Fri Sep 25, 2015 9:50 pm

Hi out there,

I run into a problem and solved it, but in a crude way. Maybe there is a smoother solution.

The problem in one sentence: How to save and restore a Pawn's AttitudeToPlayer (its an Enum) in a (static) array?
I tried it with a way like

Code: Select all

	var byte AttitudeArray[512];
...
	Pawn.AttitudeToPlayer = AttitudeArray[i]; // results in "Error, Type mismatch"
and

Code: Select all

	Pawn.AttitudeToPlayer = EAttitude(AttitudeArray[i]); // results in "Error, Bad or missing expression in '='"
and

Code: Select all

	Pawn.AttitudeToPlayer = Enum'EAttitude'(AttitudeArray[i]); // results in same as above
But an element of an Enum ist just a Byte, so there meight be a way to convert a byte into an Enum element and verce visa.


I did it finally with:

Code: Select all

var pawn PawnsAttitudeToPlayer[512];
var byte PawnsAttitudeToPlayerAttitudes[ArrayCount(PawnsAttitudeToPlayer)];
var int PawnsAttitudeToPlayerCount;


function SetAttitudeToPawn(Pawn p, byte AttitudeToPlayer) // notice the singular in function name: "Pawn"
{
	switch (AttitudeToPlayer)
	{
		case 0:
			p.AttitudeToPlayer = ATTITUDE_Fear;
			break;
		case 1:
			p.AttitudeToPlayer = ATTITUDE_Hate;
			break;
		case 2:
			p.AttitudeToPlayer = ATTITUDE_Frenzy;
			break;
		case 3:
			p.AttitudeToPlayer = ATTITUDE_Threaten;
			break;
		case 4:
			p.AttitudeToPlayer = ATTITUDE_Ignore;
			break;
		case 5:
			p.AttitudeToPlayer = ATTITUDE_Friendly;
			break;
		case 6:
			p.AttitudeToPlayer = ATTITUDE_Follow;
			break;
		default:
			log("Class MonsterHunt.SetAttitudeToPawn: unknown AttitudeToPlayer=" $ AttitudeToPlayer);
			break;
	}
}


function SetAttitudeToPawns(bool bDoRevert) // notice the plural in function name: "Pawns"
{
	local Pawn p;
	local int i;
	local bool bWarnTooManyNonHaters;

	if (bDoRevert)
	{
		foreach AllActors(class'Pawn', p)
			if (! p.IsA('PlayerPawn') && ! p.IsA('Bot'))
				p.AttitudeToPlayer = ATTITUDE_Hate;
		// restore original values:
		for (i=0; i < PawnsAttitudeToPlayerCount; i++)
			SetAttitudeToPawn(PawnsAttitudeToPlayer[i], PawnsAttitudeToPlayerAttitudes[i]);
	}
	else
	{
		bWarnTooManyNonHaters = False;
		PawnsAttitudeToPlayerCount = 0;
		foreach AllActors( class'Pawn', p)
			if (! p.IsA('PlayerPawn') && ! p.IsA('Bot'))
			{
				if (p.AttitudeToPlayer != ATTITUDE_Hate) // store all pawns different from ATTITUDE_Hate in array *PawnsAttitudeToPlayer* and their AttitudeToPlayer in array *PawnsAttitudeToPlayerAttitudes*
					if (PawnsAttitudeToPlayerCount < ArrayCount(PawnsAttitudeToPlayer))
					{
						PawnsAttitudeToPlayer[PawnsAttitudeToPlayerCount] = p;
						PawnsAttitudeToPlayerAttitudes[PawnsAttitudeToPlayerCount] = p.AttitudeToPlayer;
						PawnsAttitudeToPlayerCount++;
					}
					else
						if (! bWarnTooManyNonHaters)
						{
							Warn("Class MonsterHunt.SetAttitudeToPawns: more than" @ ArrayCount(PawnsAttitudeToPlayer) @ "pawns with AttitudeToPlayer != ATTITUDE_Hate");
							bWarnTooManyNonHaters = True; // only one warning per map
						}
				p.AttitudeToPlayer = ATTITUDE_Ignore;
			}
	}
}
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

MrLoathsome
Inhuman
Posts: 958
Joined: Wed Mar 31, 2010 9:02 pm
Personal rank: I am quite rank.
Location: MrLoathsome fell out of the world!

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by MrLoathsome » Sat Sep 26, 2015 12:41 am

Does that code actually compile?
I see a couple of issues there...

Pretty sure I have something somewhere that does exactly what you are asking, but
I don't have it all available on this PC yet.

Might have an answer for you soon, if I get my act together here.
blarg

User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by Barbie » Sat Sep 26, 2015 1:58 am

Thanks for your quick answer.
Yes, it compiles and it works as intended. I did a log-listing of every treated (Pawn.name/Pawn.AttitudeToPlayer) before saving, after changing and after restoring to compare them and to verify that peace of code.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

MrLoathsome
Inhuman
Posts: 958
Joined: Wed Mar 31, 2010 9:02 pm
Personal rank: I am quite rank.
Location: MrLoathsome fell out of the world!

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by MrLoathsome » Sat Sep 26, 2015 3:09 am

Ok, I went and tracked down the code I was thinking of.

If I recall, there where various issues and problems, the details of which I do not recall when
trying to set AttitudeToPlayer directly as you are doing.

The only way I found to get things to work right, was to set a few variables for the pawn itself, and
use calls to SetEnemy(); You also have to change the pawns current state.

Just to give you an idea of the different approach I took,
here is a brief snippet from the MutatorTakeDamage function I have in the final update of the BadNews mutator:

Code: Select all

		if ((Victim.IsA('ScriptedPawn')) && (Victim.Enemy != InstigatedBy))
		{
			ScriptedPawn(Victim).OldEnemy = Victim.Enemy;
			Victim.Enemy = InstigatedBy;
			ScriptedPawn(Victim).Hated = InstigatedBy;
			ScriptedPawn(Victim).SetEnemy(InstigatedBy);
			if (Victim.Enemy != None) Victim.gotostate('Attacking'); else Victim.gotostate('Wandering');
		}
The pawns will remember OldEnemy, and go back to that goal if the new enemy gets killed.
You should be able to adapt this to what you are trying to do. Maybe. I think... Who knows? :rock:

The full source code is included. http://www.ecoop.tk/load/badnews_rc4/1-1-0-47

Look in file BN.uc

*Edit:
The way I did it in BadNews, works with any type of pawn, but only works
as far as Enemy/OldEnemy is concerned.

You would have to add stuff to make it only restore the state for PlayerPawns or
if you wanted to use attitudes other than Attack.
blarg

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by sektor2111 » Sat Sep 26, 2015 7:26 am

Without a heavy code-push pretty sure you won't get anything.
After all, Atitude_Follow is not implemented

Facts tested
IceSkaarj Set friendly to player nearby player. Other IceSkaarj-s wild set with hate. Player hitting a trigger for those wild made them to attack. When encountered friendly IceSkaarj they pushed it into hate, and IceSkaarj was attacking player. First time it was camping nice but those wild ones triggered it to hate due to SetEnemy() cute trash. It's about AttitudeTo() which is an internal function called setting up byte depending on condition as I could see so far and for sure that one cannot be stored, and is a key for what will gonna happen later + damage attitude. HIT a pawn ignoring you and will return hate attacking - else everything on ScriptedPawn goes to attack, even the cow, but cow has a different attack formula Moo Moo - you can check and see what I mean. The only thing known by original ScriptedPawn is Attacking the rest are just words. AtittudeToPlayer yes it's a value that can be stored but won't help when you hit that pawn, and yes they might "change their mind" toward Player.

Aside see this Engine.PlayerPawn

Code: Select all

function damageAttitudeTo(pawn Other)
{
	if ( Other != Self )
		Enemy = Other;
}
This is more evilized at monster. But... taking a look over this I understood how to call help from a Bot in a heavy ambush. Simply even PlayerPawn has an enemy slot - probably in future I'll put some addon into NsMonster which I'm using, and yes the best way to deal with things correctly is to have custom creatures with things rewritten.

Did I spoke about Bump ? No ? My bad...

Code: Select all

function Bump(actor Other)
{
	local vector VelDir, OtherDir;
	local float speed;

	if ( Enemy != None )
	{
		if (Other == Enemy) //If you have shoot this pawn before then touching it
		{
			GotoState('MeleeAttack'); //Doesn't even call any attitude, it is simply attacking
			return;
		}
		else if ( (Pawn(Other) != None) && SetEnemy(Pawn(Other)) )
		{
			GotoState('MeleeAttack');
			return;
		} 
	}
..........
You can take a consideration at Mr.LoathSome's tweaks, you might need a mutator with take damage written to prevent bad things attempting a code-push to clone friendly attitude.

Else to prevent an insane sudden useless love for arrays you might setup in a small cube tiny things and see reaction in order to know what is needed. Storing these dynamic bytes leads nowhere when SetEnemy() has returned True and you are Enemy because you hit monster accidentally. Only a TakeDamage pushed tweak might help.

Edit: Some new MH2 system tends to get over SetEnemy() and Attitude things ( I suspect these guilty for more problems ) triggering battle directly so attitude deals are going to be an useless work toward Non-Monster pawn. "Bunch-Attack" might be relevant, Response at any Attacker Non-Monster, attempt to make team with other monster having even a secret TeamLeader. These were tweaks happily added completing Attitude_Frenzy at player automated in SetPawnDifficulty + reinforced as needed from server-side things, LOL.

User avatar
Barbie
Godlike
Posts: 2069
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by Barbie » Sat Sep 26, 2015 5:29 pm

Thanks again for your answers - and I see that I should have given my intention for that code: It's just to avoid that silly attacking of monsters while you are flying around before game start, so things like "Bump" or "TakeDamage" can not occur, at least not for playerpawns. With game start all AtittudeToPlayer's should be restored to their original values then. If you know a better solution for this, it's welcome.

So lets get technical again and back to my question: How to type cast Byte to an Enum? Technically it is not a problem because an Enum is just a Byte. But I don't know the syntax of this type casting nor if UCC allows it at all.
"Multiple exclamation marks," he went on, shaking his head, "are a sure sign of a diseased mind." --Terry Pratchett

JackGriffin
Godlike
Posts: 3766
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by JackGriffin » Sun Sep 27, 2015 1:08 am

Read this, then get back if you have further actual usage questions: http://wiki.beyondunreal.com/Enums
So long, and thanks for all the fish

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by sektor2111 » Sun Sep 27, 2015 6:26 am

Barbie wrote:and I see that I should have given my intention for that code: It's just to avoid that silly attacking of monsters while you are flying around before game start, so things like "Bump" or "TakeDamage" can not occur
If you check default MH + source_code, already a half of job is done - but was "fixed" later... Second part is adding a separate value for starting game and then remove any damage if game did not start based on that value preventing any possible problem - for sure Off-Line is a bit different from On-Line you might wanna check this as well - if you are a detail lover.

===Warning note===
Class Name Call MonsterHunt(Level.Game).bSomeBoolean probably will return errors IF compilation pass - old MH being called from dependencies. I prefer the tweak code into BaseMutator because is "an earlier" started one and you might wanna change game class name, suggestion only "bMH.uc" . You will subclass later a null MH in order to get game-name correctly, "class Monsterhunt expands bMH;".
===End Warning===

===Cute solution===
Te he... second fix for such problem involves multiple problems solved in a simple move. Start Monsters In state "GameEnded" and disable all Factories and active Triggers. When game has been started enable everything which were supposed active + send all monster in State "Auto" - in this way Skaarj won't drop any invisible weapon, LOL (take in account bHidden). Why so much crap code to do a simple setup ? And I'm saying this because I already have these added and functional not presumed + other things solved which are off-topic here so are not a need to go into description.
===End cute solution===

===Personal thoughts===
Yes, "Monsterhunt.uc" used into attached MH games I think is a trouble maker. You might finally reconsider that we are in 2015 and that code might be outdated - if not, reinstall WIN98SE for a perfect match and play MH with all bugs as in 2007 :rock: .
It's not silly to see monster's insane activity before game-start, I think they look the mostly retarded firing nowhere and spaming trying to attack ghost player :loool: .
I think when game initializes is too much load, 200 monsters fired in action + the rest of stuff... :noidea. I prefer a cute relaxed initialization.
===End of Thoughts===

MrLoathsome
Inhuman
Posts: 958
Joined: Wed Mar 31, 2010 9:02 pm
Personal rank: I am quite rank.
Location: MrLoathsome fell out of the world!

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by MrLoathsome » Sun Sep 27, 2015 10:22 am

Many good points there sektor.

@Barbie.

If you have no luck getting the enum thing working you may have to try a different approach.
(I suspect it might not do what you want even if you get the type casting working the
way you want for that value....)

The BadNews mutator that I posted that code snipped from, pretty much does the opposite
of your goal. (The code in BadNews attempts to make the monsters more active, and sometimes fight each other...)

But you could probably modify that code some so that it has the scripted pawns ignore everything
until the match actually begins.

Quick and dirty way might just be a bit of mutator code that keeps them all doing nothing until
the match started. It could have a quite high check rate, as nothing much else should be going on at that point.
blarg

Buggie
Adept
Posts: 421
Joined: Sat Mar 21, 2020 5:32 am

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by Buggie » Thu Jul 09, 2020 9:48 pm

Barbie wrote:
Fri Sep 25, 2015 9:50 pm
I did it finally with:
Epic too not found better way :lol2:

Code: Select all

		result = DeathMatchPlus(Level.Game).AssessBotAttitude(self, Other);
		Switch (result)
		{
			case 0: return ATTITUDE_Fear;
			case 1: return ATTITUDE_Hate;
			case 2: return ATTITUDE_Ignore;
			case 3: return ATTITUDE_Friendly;
		}
https://github.com/Slipyx/UT99/blob/a26 ... t.uc#L1973

-------

Perhaps there is one solution.

Such a thing, to be honest. And not the fact that it works.

Inherit Pawn. There, create an enum array (not sure if this is possible), and then assign the values from the method inside this class there.

Even if it works, it’s so ugly that switch is better.

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by sektor2111 » Thu Jul 09, 2020 10:18 pm

Let me explain then a few "news" which I considered good for being used in XC_MonsterHunt and... I did not see any problem so far in common maps.
Before Auto State, during relevance/skill setup, all monster claims "GameEnded" as initial state - no more bullshitting iterations for nothing (in case that nobody is playing) running initialization codes is USELESS (home, team, patrol, guard and so on). During this state, guaranteed they won't even blink...
When game starts, all creatures are starting to wake up in waves - slowly, during a few seconds everyone is ready - and here attitude is being set at maximum power because some monsters are ignoring players in low skill (even if are spawned later in game).

Code: Select all

// Manta functions.

/* PreSetMovement()
default for walking creature.  Re-implement in subclass
for swimming/flying capability
*/

function PreBeginPlay()
{
	Super.PreBeginPlay();
	if ( skill <= 1 )
		Health = 0.6 * Health;
	if ( skill == 0 )
		AttitudeToPlayer = ATTITUDE_Ignore; //Lol MH servers
}
Entertaining attitude, huh ? Because majority of servers/games have this skill 0 assigned VIA Level.Game.difficulty which can be set in run-line but no one cares...
And next reaction, No more noise before start, just allow other mutators to do their job using a lot of resources initially eaten by monsters getting ready for nobody. If Bot is not moving before starting game, why monster must fight with ghosts ? Excuse me but I'm no longer accepting this insanity - not even swarm spawners won't spawn anything when nobody is playing. Why processing for no reason ?

User avatar
TexasGtar
Skilled
Posts: 236
Joined: Sun Feb 16, 2020 5:52 pm

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by TexasGtar » Thu Jul 09, 2020 10:40 pm

This is probably zero help here but....
There is an actor called make nali friendly again that may have some code insight to changing pawns attitude ???
Not even sure what it does or if it works, Might be under keypoint? I can't remember.

User avatar
sektor2111
Godlike
Posts: 5209
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: How to save and restore a Pawn's AttitudeToPlayer?

Post by sektor2111 » Thu Jul 09, 2020 10:47 pm

That's addressing Nali which for some reason might have fear from Player.
Problem of hunting ghost player is solved when all Monster it's in Ending stage. After start, they only need a wake up and powerup attitude, the rest is native code - which can be loved in a dedicated server after all - including attacking innocent doors, lol, in servers which I set this is no longer happening... attitude is not really something to be saved unless you will use whatever actor owned by monster and then... you can save what you want over there but I'm not sure if worth spawning actors when things are doable other way more simple...

Bot problem ?
Can be solved in a different DM TDM game-type where attitude can be changed dynamically depending on game state. DeathMatchPlus has a sample of attitude code but this definitely can be divided in parts, this is not something that cannot be rewritten after needs.