Read the EDITs .o.
Feralidragon wrote:Also a remark if you allow me, I suggest you to learn De Morgan's laws (
https://en.wikipedia.org/wiki/De_Morgan%27s_laws ), because this:
Code: Select all
if (actor.IsA('Pawn') && (Pawn(actor).PlayerReplicationInfo != None) && Pawn(actor).PlayerReplicationInfo.bIsSpectator && Pawn(actor).PlayerReplicationInfo.bWaitingPlayer) {
//If the actor is a spectating pawn do nothing.
} else {
...
}
could as easily be replaced by this:
Code: Select all
if (!actor.IsA('Pawn') || Pawn(actor).PlayerReplicationInfo == None || !Pawn(actor).PlayerReplicationInfo.bIsSpectator || !Pawn(actor).PlayerReplicationInfo.bWaitingPlayer) {
...
}
or even if you don't know them:
Code: Select all
isSpectator = actor.IsA('Pawn') && (Pawn(actor).PlayerReplicationInfo != None) && Pawn(actor).PlayerReplicationInfo.bIsSpectator && Pawn(actor).PlayerReplicationInfo.bWaitingPlayer;
if (!isSpectator) {
...
}
Yes thanks, I don't know why I left it like that.
(I'll change it when this problem is fixed .o.)
Feralidragon wrote:Also, although UScript is case-insensitive, it was a good idea from him to call it "actor" with lowercase rather than "Actor", to make the reference even more plain clear.
Well, it's about good programmer rules lol, it brings to less confusion, so more readability.
Barbie wrote:Also for debugging I'd simplify that code as much as possible: use constants instead of variables and function calls, leave out unneeded code, add more log messages, don't put it into a timer but trigger that.
If you are able to melt that down to a dozen lines, you could make and publish a test map. Compiling and running that code it via brain may produce headache and dizziness.
True, I was going to do it right today, this is the first simplified version:
Code: Select all
event Timer() {
local Actor actor;
local LocationInfo nearestlocInfo, locInfo, newLocInfo;
foreach AllActors(class'Actor', actor)
if (trackActor(actor) || actor.IsA('Bot') || actor.IsA('PlayerPawn')) {
//FIXME
Level.Game.BroadcastMessage(0@actor);
if (actor.IsA('Pawn') && (Pawn(actor).PlayerReplicationInfo != None) && Pawn(actor).PlayerReplicationInfo.bIsSpectator && Pawn(actor).PlayerReplicationInfo.bWaitingPlayer) {
//If the actor is a spectating pawn do nothing.
} else {
foreach actor.RadiusActors(class'LocationInfo', locInfo, 100) {
//FIXME
Level.Game.BroadcastMessage(1@actor);
nearestlocInfo = locInfo;
}
//FIXME
Level.Game.BroadcastMessage(2@actor@nearestlocInfo);
if (nearestlocInfo == None)
newLocInfo = Spawn(class'LocationInfo', Self,, actor.Location);
}
}
}
The problem is still there, player makes it print 0,1,2 while Nali makes it print 0,2(and nearestLocInfo is not None).
if I change the Radius from 100 to 5000, even the Nali goes 0,1,2.
(Also, there's no need to let the Nali moves, the nearestLocInfo should still spawn even if the Nali is next to me, so I'm not hurting him anymore)
EDIT: Looks like Level.Game.BroadcastMessage() wasn't fast enough to print all the logs... I added some logs info, now the code looks like this:
Code: Select all
event Timer() {
local Actor actor;
local LocationInfo nearestlocInfo, locInfo, newLocInfo;
//FIXME
Level.Game.BroadcastMessage(-1@nearestlocInfo);
foreach AllActors(class'Actor', actor)
if (trackActor(actor) || actor.IsA('Bot') || actor.IsA('PlayerPawn')) {
//FIXME
Level.Game.BroadcastMessage(0@actor@nearestlocInfo);
if (actor.IsA('Pawn') && (Pawn(actor).PlayerReplicationInfo != None) && Pawn(actor).PlayerReplicationInfo.bIsSpectator && Pawn(actor).PlayerReplicationInfo.bWaitingPlayer) {
//If the actor is a spectating pawn do nothing.
} else {
foreach actor.RadiusActors(class'LocationInfo', locInfo, 100) {
//FIXME
Level.Game.BroadcastMessage(1@actor@nearestlocInfo);
nearestlocInfo = locInfo;
//FIXME
Level.Game.BroadcastMessage(2@actor@nearestlocInfo);
}
//FIXME
Level.Game.BroadcastMessage(3@actor@nearestlocInfo);
if (nearestlocInfo == None) {
newLocInfo = Spawn(class'LocationInfo', Self,, actor.Location);
//FIXME
Level.Game.BroadcastMessage(4@actor@nearestlocInfo@newLocInfo);
}
}
}
}
Logs I get with BroadcastMessage():
Code: Select all
ScriptLog: -1 None
ScriptLog: 0 CTF-Niven.TMale2 None
ScriptLog: 1 CTF-Niven.TMale2 None
ScriptLog: 2 CTF-Niven.TMale2 CTF-Niven.LocationInfo0
ScriptLog: 3 CTF-Niven.TMale2 CTF-Niven.LocationInfo0
ScriptLog: 0 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo0
ScriptLog: 1 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo0
Logs I get with Log():
Code: Select all
ScriptLog: -1 None
ScriptLog: 0 CTF-Niven.TMale2 None
ScriptLog: 1 CTF-Niven.TMale2 None
ScriptLog: 2 CTF-Niven.TMale2 CTF-Niven.LocationInfo0
ScriptLog: 3 CTF-Niven.TMale2 CTF-Niven.LocationInfo0
ScriptLog: 0 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo0
ScriptLog: 1 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo0
ScriptLog: 2 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo0
ScriptLog: 3 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo0
This has a lot more sense now -__-".
It is very annoying to debug it through logs instead than broadcasted messages when you're working with visible stuff in game
EDIT 2: WAIITTTT, I changed the code back to this:
Code: Select all
event Timer() {
local Actor actor;
local LocationInfo nearestlocInfo, locInfo, newLocInfo;
foreach AllActors(class'Actor', actor)
if (trackActor(actor) || actor.IsA('Bot') || actor.IsA('PlayerPawn')) {
//FIXME
Log(0@actor);
if (actor.IsA('Pawn') && (Pawn(actor).PlayerReplicationInfo != None) && Pawn(actor).PlayerReplicationInfo.bIsSpectator && Pawn(actor).PlayerReplicationInfo.bWaitingPlayer) {
//If the actor is a spectating pawn do nothing.
} else {
foreach actor.RadiusActors(class'LocationInfo', locInfo, minDist - actor.CollisionRadius, actor.Location) {
//FIXME
Log(1@actor);
if (locInfo.isGoodCandidate(actor.class))
if ((nearestlocInfo == None) || VSize(locInfo.Location - actor.Location) < VSize(nearestlocInfo.Location - actor.Location))
if (FastTrace(actor.Location, locInfo.Location))
nearestlocInfo = locInfo;
}
//FIXME - nearestLocInfo is never None for the Nali even if the logs show 0 and 3 only.
//(case steps:
//1. You start the match alone;
//2. You don't move and spawn a Nali;
//3. You hurt the Nali and let it moves away.)
Log(2@actor@nearestlocInfo);
if (nearestlocInfo == None) {
newLocInfo = Spawn(class'LocationInfo', Self,, actor.Location);
newLocInfo.actorClass = actor.class;
newLocInfo.attentionLevel++;
} else {
nearestlocInfo.attentionLevel++;
}
}
}
}
Replacing messages with logs, but logs came back like this:
Code: Select all
ScriptLog: 0 CTF-Niven.TMale2
ScriptLog: 1 CTF-Niven.TMale2
ScriptLog: 2 Botpack.TMale1 Botpack.TMale1 Vero
ScriptLog: 3 CTF-Niven.TMale2 CTF-Niven.LocationInfo2
ScriptLog: 0 CTF-Niven.NaliPriest0
ScriptLog: 3 CTF-Niven.NaliPriest0 CTF-Niven.LocationInfo2
F*** that o\/o
Maybe code flow is too fast even for native Logs?
(The timer interval is set to 1)
EDIT 3: The issue only occurs when the Nali moves away from me, if he stays next to me, the logs for the Nali are 0,1,2, but if he moves away the logs for the Nali print 0,2. In both the cases, when it prints 2, the nearestLocInfo is still the same, the one that is used by the player(which is a bug since a new one should be spawned right for the Nali class instead).