Okay, in all seriousness this is my current method:
area
npc_area
icon = 'area.dmi'
layer = MOB_LAYER + 1
var
tmp
list
active_players = list()
New()
src.icon = null
// This is to help with map-making. What I'm doing is having it so you can physically make the /areas on the map editor
// and it will be visible on the map editor, but in run-time the /areas are going to be blank.
// When placing down NPC(s), create a new enemy_bounds/guard_bounds area for it, example:area_one, area_two, etc.
// This will be the "bounding area" the NPC can be activated at. If a player steps in this area, they will active the NPC's located
// in the area. To prevent NPC's from escaping the area, place the /area/npc_area/stop_npc around the "bounding area", otherwise
// the NPC's won't be deactivated and they'll roam around the whole place with no stop.
..()
stop_npc
icon = 'area.dmi'
icon_state = "stop"
layer = MOB_LAYER + 1
Enter(object)
if(istype(object, /mob))
var/mob/possible_npc = object
if(!possible_npc.client)
return FALSE
else
return TRUE
Entered(object)
var/mob/player
if(istype(object, /mob))
player = object
src.active_players += player
if(player.client)
for(var/mob/possible_npc in src)
if(!possible_npc.client)
possible_npc.ai_active = 1
possible_npc.ai_area = src
Exited(object)
var/mob/player
if(istype(object, /mob))
player = object
src.active_players -= player
if(src.active_players.len < 1)
for(var/mob/possible_npc in src)
if(!possible_npc.client)
possible_npc.ai_active = 0
possible_npc.target = null
enemy_bounds
area_one
// This is where X will be.
area_two
// This is where X will be.
area_three
// This is where X will be.
area_four
// This is where X will be.
area_five
// This is where X will be.
guard_bounds
area_one
// This is where X will be.
area_two
// This is where X will be.
area_three
// This is where X will be.
area_four
// This is where X will be.
area_five
// This is where X will be.
mob
proc
npc_AI()
while(src)
if(src.ai_active)
if(src.target)
src.npc_goToTarget()
else
src.npc_randomMove()
sleep(world.tick_lag)
npc_randomMove()
if(src.target)
src.npc_goToTarget()
else
var/direction = list(1, 2, 4, 5, 6, 8, 9, 10)
var/direction_to_walk = pick(direction)
for(var/loop = 1, loop < rand(25, 50), loop++)
src.movement(direction_to_walk)
sleep(world.tick_lag)
src.npc_findTarget()
npc_goToTarget()
if(src.target)
if(!src.target in src.ai_area)
src.target = null
src.movement(pick(list(1, 2, 4, 5, 6, 8, 9, 10)))
else
src.movement(get_dir(src, src.target))
if(bounds_dist(src, src.target) <= src.bound_width)
flick(pick(list("punch", "punch2", "kick", "kick2")), src)
sleep(src.attack_delay + world.tick_lag)
// Replace last 2 lines of code with damage(src, src.target) proc
npc_findTarget()
src.target = null
for(var/mob/possible_target in src.ai_area)
if(possible_target.client)
src.target = possible_target
walk_npc
step_size = 2
icon = 'human.dmi'
New()
generateShadow(src, "SOUTHEAST", 75)
spawn() src.npc_AI()
..()
/mob/proc/movement() is just
step(src, direction, src.step_size)
Network wise when hosting it's great. The movement is smooth and the walk_npc function as they should. However, I notice world.cpu reaches ridiculous heights of almost 1-2 CPU per walk_npc placed on the map. So, about 40 walk_npc generates about 50-60 world.cpu.
Player's step_size is changeable from 2, 6, 8.
world.fps @ 40, tick_lag @ 0.25, icon_size @ 32.
The Profiler shows this (Average):
npc_randomMove Self(0.000) Total(0.002) Real(0.727) Calls(18,754)
npc_goToTarget Self(0.000) Total(0.002) Real(0.004) Calls(4,869,971)
stop_npc Enter Self(0.000) Total(0.002) Real(0.004) Calls(77,748)
stop_npc Entered Self(0.000) Total(0.002) Real(0.004) Calls(108)
stop_npc Exited Self(0.000) Total(0.002) Real(0.004) Calls(108)
movement Self(0.000) Total(0.002) Real(0.004) Calls(5,420,838)
Is there something I'm missing as far as making this more efficient?
Also, I noticed that when hosting the other player's movements are choppy, but /mob/walk_npc movement is perfect. Is this a networking issue (I don't have the best internet so I'm fairly certain it's my connection.)
Is world.cpu dependent on the hosting machine's performance? Will hosting with a more powerful machine actually reduce the world.cpu figures, or is it plain and simply the same figures for one machine compared to a machine that runs 10x better?
Remember that calls rand() every time the condition is checked. The odds of this loop making it to 50 are astronomical. I think you want to pre-calculate that.