View Full Version : Need help with a simple code revision
Grimshad
01-07-2009, 02:08 PM
This forum has been pretty helpful so I'm going to request some more :P
I can't seem to figure out how to code this so it will work
////Checks if you can place a building in this area
function bool CheckArea(int bm, vector loc)
{
local building st, s;
local float dist;
////Checks if Build Areas is toggled on
if(bm==5 || !mygame(level.Game).BuildAreas) return true;
////Checks every time a new building is placed
foreach DynamicActors(class'mypackage.building',st)
{
//// If mainA or mainB is same team, allow building placement in their distance area
if((mainA(st).myteam==myteam || (mainB(st).myteam==myteam && mainB(st).grade>0)) && (s==none || vsize(st.location-loc)<vsize(s.location-loc)))
s=st;
}
////Gives the distance from mainA/mainB that you can build
dist=(float(mygame(level.Game).maindist)*48)-vsize(s.location-loc);
////If in range then distance = 0 and if distance = 0 then this returns true allowing you to build
if(dist>=0) return true;
////If distance doesn't = true then send build fail message with distance to nearest build area displayed
else Playercontroller(instigator.controller).ReceiveLoc alizedMessage(class'mypackage.AreaFailMsg',dist/-48,,,s);
return false;
////mainA and mainB extend building, when any structure extending building is placed, this code makes a check on ALL building children instead of just mainA and mainB
}
Like I said for some reason I can't figure out how to make this work
The problem is the (st) after each class mainA and mainB so the myteam==myteam checks st(building) instead of mainA and mainB
I can't think of a way to stop that from happening
Main Problem code:
if((mainA(st).myteam==myteam || (mainB(st).myteam==myteam && mainB(st).grade>0)) && (s==none || vsize(st.location-loc)<vsize(s.location-loc)))
INIQUITOUS
01-08-2009, 07:22 AM
Can you try explaining better what you are trying to do, I do not understand :/
Grimshad
01-08-2009, 07:32 AM
Everything is explained in the comments in the code,
I want to check if MainA or MainB is team 0 and if it is then allow building placement
But as you can see on there Building=st
When I put MainA(st).myteam==myteam the code checks if Building is team 0, not MainA
MainA and MainB extend Building
If I remove (st) then I get compilation error
The only way I can think of doing it is add a check in Building that says If MainA.myteam=0 then MyVariable=true
Then use MainA(st).MyVariable==true
but I don't want to add more code
Understand?
Siberion
01-08-2009, 07:33 AM
I'd like to try helping you, but I don't quite understand the problem. Could you please rephrase this:
The problem is the (st) after each class mainA and mainB so the myteam==myteam checks st(building) instead of mainA and mainB
Is it relevant where the variable "myteam" comes from, and if so, where does it come from?
Is it possible that mainA(st) or mainB(st) evaluate to None and that this causes problems?
EDIT: Well damn, I type slow o.O
EDIT 2:
I understand that MainA is a class that extends Building, correct? In that case, the myteam variable of MainA would be inherited from Building, and Building.myteam is the same variable/memory as MainA(Building).myteam. I'm not sure what you're trying to achieve.
Are MainA and MainB supposed to be classes which correspond to team red and team blue? If that is the case, have you set the variable myteam to the appropriate values in the defaultproperties section of class MainA and class MainB?
INIQUITOUS
01-08-2009, 07:46 AM
to me something doesn't look right with the if statement but I cant pin it down without actually compiling it myself. I would break up/remove the if statement into several if's just to find out where the problem is then simplify it again after its fixed.
Also you could try a different way like..
if(st.IsA('MainA') && st.myteam == myteam)
I hope this gives you new ideas!
Also adding the extra boolean check wont break the engine ;)
edit: I type slow also lol Siberion
edit 2: just a note. I work with monsters a lot and I always have to do checks for 'Monster' and its variables etc.. I often find that using the .IsA is the best way to go, it never seems to fail ;) also you can set it to check actors that don't even exist! allowing for future custom content.
Grimshad
01-08-2009, 09:20 AM
Are MainA and MainB supposed to be classes which correspond to team red and team blue? If that is the case, have you set the variable myteam to the appropriate values in the defaultproperties section of class MainA and class MainB?
Ok the variable myteam is declared in Building
but I don't need to check if Building is my team, I need to check if MainA or MainB is my team
this code is in MainA and MainB
simulated function setinitialteam(int t)
{
MyTeam=t;
defenderteamindex=byte(t);
if(myteam==0) setStaticMesh(StaticMesh'MyPackage.Buildings.MainA ');
else setStaticMesh(StaticMesh'MyPackage.Buildings.MainA blue');
}
This checks which team "Building" belongs to and then sets the mesh acordingly
Well now I need to check which team "MainA" belongs to
could I possibly just check the mesh == MainA?
I don't know what the code for that would be.
INIQUITOUS
01-08-2009, 10:04 AM
you could make a function that returns the int of the team and then call that function in the if statement instead.
otherwise if you go the mesh way its something like
if(Building.StaticMesh == StaticMesh'MyPackage.MainA')
i think, however wormbo is doing his rounds i think and would know more.
Wormbo
01-08-2009, 10:27 AM
Likethe others already said: Your code fails to check whether the object referenced by the st variable actually is a MainA or a MainB before trying to access its myteam property.
As an example to clarify the problem, let's just assume we're in the first iteration of the foreach loop and st refers to a MainB-type building with a myteam value of 1. Let's also assume that the myteam property of the object executing that code is 0. Your code inside the foreach loop goes: "if((mainA(st).myteam==myteam || ...) && (s==none || ...)) s=st;"
So, according to your loop we have a Building object that, according to our assuptions, is of type MainB. I guess MainA and MainB are siblings, so a Building can only be of type MainA or MainB, but never both. Now your code typecasts the Building in st to type MainA. Since it's not actually a MainA, this typecast results in the value None. Now your code accesses "None.myteam", which will log an "Accessed None" warning to the log file and return the null value for the data type of the myteam variable, i.e. 0.
We assumed that the myteam property of the object executing this code is 0, so we get (None.myteam=0) == (myteam=0), i.e. True. The other operand of the || operator is skipped as the first one laready evaluated to True, so the first operand of the && operator also evaluated to True. Since it's the first iteration, s is still None, so the second operand of the && also evaluates to True. The If condition is True, so s=st is executed.
Now I don't know what other Building objects you have in your map, but let's assume they are all further away from Loc than our assumed first MainB-type Building object currently stored in s. In this case the foreach loop will not assign any other Building objects to s anymore (although it might log further Accessed Nones) and you end up with a building of the wrong team in s.
After this lengthy explaination about why your code fails, here's a possible fix. Change the If condition inside the ForEach loop to: "st.myteam == myteam &&(MainA(st) != None || MainB(st) != None && MainB(st).grade>0) && (...)"
This will first check whether the typecast to the specified class is actually successful before attempting to access any members of that type.
Grimshad
01-08-2009, 11:06 AM
INIQUITOUS, I typed that StaticMesh code in and then realized that if It checks if the mesh is red teams mesh then there is no check for blue, and you will only be able to build inside of red teams build area.
K sorry wormbo, but I am not skilled enough to understand eveything you said about the failure, However your example is brilliant :)
INIQUITOUS
01-08-2009, 11:25 AM
That was just an example of how I thought the syntax was.
Try Wormbos way, he said change this
if((mainA(st).myteam==myteam || (mainB(st).myteam==myteam && mainB(st).grade>0)) && (s==none || vsize(st.location-loc)<vsize(s.location-loc)))
to
if(st.myteam == myteam &&(MainA(st) != None || MainB(st) != None && MainB(st).grade>0) && (s==none || vsize(st.location-loc)<vsize(s.location-loc))
Grimshad
01-08-2009, 11:42 AM
Oh I did and it works perfectly, I thought I made that clear in my last post.
anyway, Thanks again Wormbo :)
Grimshad
01-09-2009, 12:26 AM
Argg, I just got done testing the code with blue team(which i forgot to do when i first applied it)
The code is only allowing team 0 and team 1 to build in team 0's area
fixed it by using
instigator.PlayerReplicationInfo.Team.teamindex
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.