The Health of StationaryPawn

Discussions about Coding and Scripting
User avatar
Gadavre
Skilled
Posts: 176
Joined: Sun Jan 18, 2015 7:55 am

The Health of StationaryPawn

Post by Gadavre »

This StationaryPawns (TeamCannon and MinigunCannon) has a default of 220 health. I want to reduce their Health . but I cant. It is possible to do in Mutator class?
I was looking for a solution. This does not work in many functions.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: The Health of StationaryPawn

Post by Higor »

If you don't feel like messing with defaults, you can just loop.

The below code will also regenerate cannons that have no enemy and are idle.

Code: Select all

event Timer()
{
    local TeamCannon TC;

    ForEach PawnActors (class'TeamCannon', TC) //XC_Engine iterator
        if ( (TC.Health > 150) ||  (TC.Enemy == none && TC.Health > 0) )
            TC.Health = 150;
}
User avatar
Barbie
Godlike
Posts: 2953
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: The Health of StationaryPawn

Post by Barbie »

Gadavre wrote:This StationaryPawns (TeamCannon and MinigunCannon) has a default of 220 health. I want to reduce their [StationaryPawns] Health
I guess you are running a server and want to reduce the health for StationaryPawns of maps the server loads? If so, put the following code into a Mutator or any Actor running as ServerActor:

Code: Select all

Event PostBeginPlay() {
local StationaryPawn SP;

	ForEach AllActors(Class'StationaryPawn', SP)
	{
		// changing the default value is needed because in state
		// 'DamagedState' the Health is reset to default value
		SP.default.health = 123; // your new health
		SP.Health = SP.Default.Health;
	}
}
"If Origin not in center it be not in center." --Buggie
User avatar
Gadavre
Skilled
Posts: 176
Joined: Sun Jan 18, 2015 7:55 am

Re: The Health of StationaryPawn

Post by Gadavre »

Higor Barbie
Thank you, coders! :tu:

--edit by UnrealGGecko--
Barbie wrote:
Gadavre wrote:This StationaryPawns (TeamCannon and MinigunCannon) has a default of 220 health. I want to reduce their [StationaryPawns] Health
I guess you are running a server and want to reduce the health for StationaryPawns of maps the server loads? If so, put the following code into a Mutator or any Actor running as ServerActor:

Code: Select all

Event PostBeginPlay() {
local StationaryPawn SP;

	ForEach AllActors(Class'StationaryPawn', SP)
	{
		// changing the default value is needed because in state
		// 'DamagedState' the Health is reset to default value
		SP.default.health = 123; // your new health
		SP.Health = SP.Default.Health;
	}
}
your Code works! But I would like it to work online and offline! I have to say that your code conflicts with my function PostBeginPlay() And i would like to reduce health only on cannons. So I changed it

Code: Select all

function PostBeginPlay()
{
	local TeamCannon TC;
	local MinigunCannon MC;

   ForEach AllActors(Class'TeamCannon', TC)
   {
      TC.default.health = 10; // your new health
      TC.Health = TC.Default.Health;
   }
   ForEach AllActors(Class'MinigunCannon', MC)
   {
      MC.default.health = 10; // your new health
      MC.Health = MC.Default.Health;
   }
}
Last edited by UnrealGGecko on Mon Dec 25, 2017 9:59 pm, edited 2 times in total.
Reason: Posts merged, please avoid doubleposting.
User avatar
Barbie
Godlike
Posts: 2953
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: The Health of StationaryPawn

Post by Barbie »

Keep in mind that "AllActors(Class'WhatEver')" treats not only Actors of class 'WhatEver' but its sub classes also - and then there are some surprises out there: If you run above code in a Mutator and load a map that uses pawns of package "TeamMonster.u" for example, all that monsters are treated, too, because pawns of that package are sub classes of 'TeamCannon'.

If I want to be sure to treat a certain class only I use

Code: Select all

ForEach AllActors(Class'TeamCannon', TC)
	if (TC.Class == Class'TeamCannon') // don't treat sub classes
	{
		TC.default.health = 10;
		TC.Health = TC.Default.Health;
	}
"If Origin not in center it be not in center." --Buggie
User avatar
sektor2111
Godlike
Posts: 6442
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: The Health of StationaryPawn

Post by sektor2111 »

@Gadavre - So if you have 20 types of cannons you will use 20 iterators ?
This is not the way of coding stuff seriously. You can test all sort of cannons using ONE single iterator and checking classes:

Code: Select all

foreach AllActors(class'TeamCannon', T)
{
	if (T.class == class'TeamCannon')
	{
		T.default.health =...;
	}
	else if ( T.Class == class'MinigunCannon' )
	{
		T.default.health =...;
	}
	else //OTHER UNKNOWN TYPE goes here
		T.default.health =...;
}
You really don't need a bunch of iterators which are laggers if map is bigger. You can even except child classes of TeamMonster.u (so called monsters - just copied trash from original monster and not changed accordingly).
JackGriffin
Godlike
Posts: 3776
Joined: Fri Jan 14, 2011 1:53 pm
Personal rank: -Retired-

Re: The Health of StationaryPawn

Post by JackGriffin »

IsA is right up there with the worst offenders in mods written by people who are new. This concept should have it's own detailed explanation in the coding section.
So long, and thanks for all the fish
nogardilaref
Masterful
Posts: 577
Joined: Tue Jun 20, 2017 1:00 pm
Personal rank: ⚋⚊⚌☰⚞⌖⚟☰⚌⚊⚋

Re: The Health of StationaryPawn

Post by nogardilaref »

sektor2111 wrote:@Gadavre - So if you have 20 types of cannons you will use 20 iterators ?
This is not the way of coding stuff seriously. You can test all sort of cannons using ONE single iterator and checking classes: [...]
I will just chime in and state that using a single iterator with class checks internally rather than using multiple iterators is not always the best idea.
In this case it makes all the sense as the number of expected actors belonging to class'TeamCannon' is very small, so multiple iterators here is indeed a bad idea.

However, should you have something which iterates to nearly all actors for example, is best to use one iterator for each major class, given the time the engine will take to yield the result back to the UScript level, having it processed there and then continue with the rest of the cycle, it ends up being faster having the engine itself to do that filtering, even if it means doing multiple full cycles internally.
The less time the engine has to spend on the UScript level of things, the better, even if from UScript point of view it seems to make more sense.
User avatar
Gadavre
Skilled
Posts: 176
Joined: Sun Jan 18, 2015 7:55 am

Re: The Health of StationaryPawn

Post by Gadavre »

sektor2111
sektor2111 wrote:@Gadavre - So if you have 20 types of cannons you will use 20 iterators ?
This is not the way of coding stuff seriously. You can test all sort of cannons using ONE single iterator and checking classes:

Code: Select all

foreach AllActors(class'TeamCannon', T)
{
	if (T.class == class'TeamCannon')
	{
		T.default.health =...;
	}
	else if ( T.Class == class'MinigunCannon' )
	{
		T.default.health =...;
	}
	else //OTHER UNKNOWN TYPE goes here
		T.default.health =...;
}
.
you wrote with an error. your code does not work. Barbie variant is more correct. you need to add a line

Code: Select all

T.Health = T.Default.Health;
And UCC.exe doesn't want to compile if you add the class 'MinigunCannon'. I wrote according to your sample.

Code: Select all

function PostBeginPlay()
{
local TeamCannon T;

Super.PostBeginPlay();
foreach AllActors(class'TeamCannon', T)
{
   if (T.class == class'TeamCannon')
   {
      T.default.health = 10;
      T.Health = T.Default.Health;
   }
   else ( T.Class == class'MinigunCannon' )
   {
      T.default.health = 10;
      T.Health = T.Default.Health;
   }
}
}
-MERGED-

I fixed the code. Is this code perfect? the goal is to reduce health only for cannons

Code: Select all

function PostBeginPlay()
{
local StationaryPawn SP;

Super.PostBeginPlay();
foreach AllActors(class'StationaryPawn', SP)
{
   if (SP.class == class'TeamCannon')
   {
      SP.default.health = 10;
      SP.Health = SP.Default.Health;
   }
   else if (SP.class == class'MinigunCannon')
   {
      SP.default.health = 10;
      SP.Health = SP.Default.Health;
   }
}
}
Last edited by Gadavre on Tue Dec 26, 2017 12:10 pm, edited 1 time in total.
User avatar
Barbie
Godlike
Posts: 2953
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: The Health of StationaryPawn

Post by Barbie »

Gadavre wrote:I fixed the code.
That looks good, yes.
"If Origin not in center it be not in center." --Buggie
User avatar
sektor2111
Godlike
Posts: 6442
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: The Health of StationaryPawn

Post by sektor2111 »

Gadavre wrote: you wrote with an error. your code does not work. Barbie variant is more correct
Clearly you don't get the point, not even closer. I posted some samples to put that thing wrapped as you want NOT TO COMPILE BLINDLY snippets from forum. First of all you can adjust default Cannon health right from start, but you can do this even later and adjusting already existent cannons from Level - I wrote Cannon things in MH and I can deal with them, no worries. For writing this task I don't have issues but you do, Copy-Paste will never help in getting things with a logic - I'm friendly speaking here.
I assure you that I can write these simple things as should, but seriously, this is YOUR mod not my mod, so try to figure the logic behind these codes writing them as they should and even better.

Because you have remember me, before finishing what I'm working on, I'll share that sniper mod tool which I promised after a final check.

But... nvm. I can do this cannon spree even without iterators using another two methods... but I won't share code as long as "it's wrong" :lol2: so I'll share it another time... Any admin can use that configurable how wants.
User avatar
Gadavre
Skilled
Posts: 176
Joined: Sun Jan 18, 2015 7:55 am

Re: The Health of StationaryPawn

Post by Gadavre »

After a thorough test, I realized that this code is not ideal.

Code: Select all

function PostBeginPlay()
{
local StationaryPawn SP;

Super.PostBeginPlay();
foreach AllActors(class'StationaryPawn', SP)
{
   if (SP.class == class'TeamCannon')
   {
      SP.default.health = 10;
      SP.Health = SP.Default.Health;
   }
   else if (SP.class == class'MinigunCannon')
   {
      SP.default.health = 10;
      SP.Health = SP.Default.Health;
   }
}
}
In this code there is a bug. If the player played with my Mutator and then removes it from "Mutators used", the changed health is saved in the memory of the game. If the player starts to play in the original game, the cannons will have changed health. This code influences the original game code. The player must exit the game to clear the memory. It is possible to fix it?
User avatar
sektor2111
Godlike
Posts: 6442
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: The Health of StationaryPawn

Post by sektor2111 »

Because that "functional" code do changes class's property not pawn's default property which is not the same thing. By playing OFF-Line, garbage objects are not entirely removed from memory and variables changed by mutator are held in memory, and then in next session of the same map even without mutator Cannons are remaining screwed up because this thing was doing something like a "consolecommand". Even in some servers such things are doing permanent changes turning things in an ugly way.
Ok, after Christmas I'll write a small toy accordingly...
User avatar
papercoffee
Godlike
Posts: 10529
Joined: Wed Jul 15, 2009 11:36 am
Personal rank: coffee addicted !!!
Location: Cologne, the city with the big cathedral.

Re: The Health of StationaryPawn

Post by papercoffee »

@Gadavre

This is now the second time a staff member had to merge your posts.
NO DOUBLE POSTS!
Use the Edit button in the right corner of your post to add new content.
User avatar
Barbie
Godlike
Posts: 2953
Joined: Fri Sep 25, 2015 9:01 pm
Location: moved without proper hashing

Re: The Health of StationaryPawn

Post by Barbie »

Gadavre wrote:After a thorough test, I realized that this code is not ideal.
yes, it changes the default value, what is not the best way of programming. But blame the coder of TeamCannon for it, he is restoring the health from the default value after the health is exhausted. A better solution would have been to save the initial health in a private variable and restore it from there.

To solve the matter in a clean way, recode TeamCannon.
"If Origin not in center it be not in center." --Buggie