ID:1399298
 
(See the best response by Ter13.)
So, I want to replace instances of view/oview(digit) with a Viewers code, as I've read it takes any mob that has the src of the code in it's view range.

How would I go about setting this up, can I imply it in a for loop, or even a while loop?

Thanks ahead!

Not sure what your question is.

You can call viewers(src) just about anywhere. I'm not sure if it can be used as a setting for a verb, but that's because I don't use clickable verbs.
It's not for a verb, it's for my walk procs.

But when I replace let's say viewers(src) with view(6), all the code lines underneath it within the proc show up as underfined var in the error log

example
North(mob/M in viewers(src))
if(!src.Frozen)
step(src,NORTH)
if(mob/M in viewers(src)&&M.NPC&&!M.NpcActive)
M.NpcActive = 1
Best response
That's because you are never defining M.

You can't use an if like that. You need a "for x in y" statement to iterate through a list of values.

for(var/mob/M in viewers(src))
if(M.NPC&&!M.NpcActive)
M.NpcActive = 1


Of course, I should point out that you are using a polymorphic language. Use that to your advantage. You are storing the type of mob in a variable called NPC? Yeah, that's a terrible idea.

mob
combatant
var
Frozen
//all combat behavior should go here
player
//all player behavior should go here
NPC
var
NpcActive = 0
//all NPC behavior should go here
shopkeeper
//shopkeepers aren't combatants, thus can't be harmed, for instance.


Now that you are using polymorphism properly, you can do something like this:

for(var/mob/NPC/N in viewers(src))
N.NpcActive = 1


If you use polymorphism to your advantage, your code will be a lot more efficient, and it will be less buggy.
I did as you suggested, and started placing my vars in lists, but I still get the error that it registers functions below as undefined.

if(!src.Frozen)
step(src,NORTH)
for(var/mob/combat/NPC/M in viewers(src))
M.NpcActive = 1
South()
if(!src.Frozen)
step(src,SOUTH)

mob/combat/var
NPC
var
NpcActive = 0

gives up the next src.frozen as undefined

Ohh, and while we're at it. I need to make a function to De-activate mobs as well. Could I use mob/M in view(#,#) for that?

How does BYOND register the numbers?

example
mob/M in view(2,3)

Does it start at 2 tiles away, and searches till the third
or
Does it start at 2 tiles away, and searches 3 tiles ahead
?
What scope are you defining North()/South()/East()/West() under? If Frozen is undefined, src is not the right type to have access to that variable.

Look up view() in the reference. It does not accept multiple numbers.

The range of all the range procs (view/viwers/hearers/range/oview/orange/etc) must be squares. The range is defined as x tiles from the center of ref, so:

range(5,src)


would return all objects in an 11x11 square centered around src.

If you want to use rectangles, you will want to use bounds()
Ahh, so I can't isolate the search to a specific range starting somewhere else than the source itself?

Also, I've got the following now
        if(!usr.Frozen)
step(usr,NORTH)
for(var/mob/combat/NPC/M in viewers(usr))
M.NpcActive = 1

Somehow using usr instead of src fixed the problem, I assume because another reference (M) is being thrown in the mix

Now I get the error that M is an undefined type, why is this?
Nevermind as far as that goes, 2AM with a sinusinfection does not do my coding well, had a list within a list. Resolved the issue.


But still, I can't search an area around the user starting somewhere else than the user itself?

I basically need to make a second proc that turns hostile mobs inactive again if their target moves out of their view
Don't use usr in procs.

The reason that you are having undefined variable errors is because you are using polymorphism wrong.
How would I resolve that? Because using user instead of source resolved all compiling errors I had in the code.

But I still need to somehow impliment a search in either the walk procs or in the npc procs that 1.deactivates npcs just outside of the activate range or 2.Deactivates npcs if they can't find any players within their view
Well, you need to understand what src and usr represent really. src is the object the procedure is on, so just the same as 'this', in C++, which I've seen you mention elsewhere.

usr is the object that called the procedure or verb. There lies the problem, much of the time, with using usr in procedures.

mob
var/counter = 0

proc
Procedure1()
usr.counter++

Procedure2()
Procedure1() // Just call the other one.

Procedure3()
call(src, /mob/proc/Procedure1)


Because usr depends on who does the call, it's very context-sensitive. If I call Procedure1() on a mob, from another mob, then my counter is incremented. If I call Procedure2() from another mob, the mob I called Procedure2() on is incremented, if I call Procedure3() from anywhere, I'll get a null runtime as usr is not set in that call().

With verbs, usr is a lot more fixed. It'll be the mob of the real-world user that clicked a button, link etc in their UI to cause the verb to be called.

----

Going back to your problem, you need to decide which object it is that you want to use as the centre of the range() call. Who, on the map, is the centre or origin of that check? Then, either use src, or pass in a variable to the procedure accordingly, with the object you want to use.
Yeah, so what I wanted to implement for simplicity simply won't pass in BYOND.


What I had in mind was the same search proc within the walk code, but the search STARTS 6 tiles ahead around the user, and searches 2 tiles ahead from that point.

Instead, I could place a search proc onto each npcs movement, searching for a client in its view, and if it can't find one it becomes inactive.

Understanding code comes easy to me, but the problem with me lies that I'm doing HTML5,CSS,C#,C++ and BYOND all simultaniously, thus I tend to use codes from different languages that just won't fly in the current language