Movement
movement(ticks)
#ifdef LIBRARY_DEBUG
if(trace) trace.event("[world.time]: start movement:")
#endif
var/turf/t = loc
// if you don't have a location you're not on the map so we don't
// need to worry about movement.
if(!t)
#ifdef LIBRARY_DEBUG
if(trace) trace.event("[world.time]: end movement:")
#endif
return
// This sets the on_ground, on_ceiling, on_left, and on_right flags.
set_flags()
// apply the effect of gravity
gravity()
// handle the movement action. This will handle the automatic behavior
// that is triggered by calling move_to or move_towards. If the mob has
// a client connected (and neither move_to/towards was called) keyboard
// input will be processed.
action(ticks)
// set the mob's icon state
set_state()
// perform the movement
pixel_move(vel_x, vel_y)
#ifdef LIBRARY_DEBUG
if(trace) trace.event("[world.time]: end movement:")
#endif
Action
// The action proc is called by the mob's default movement proc. It doesn't do
// anything new, it just splits up the code that was in the movement proc. This
// is useful because the movement proc was quite long and this also lets you
// override part of the mob's movement behavior without overriding it all. The
// movement proc's default behavior calls gravity, set_flags, action, set_state,
// and pixel_move. If you want to change just the part that is now action, you
// used to have to override movement and remember to call gravity, set_flags,
// set_state, and pixel_move. Now you can just override action.
//
// To be clear, there are still cases where you'd want to override movement. If
// you want to create a bullet which travels in a straight line (isn't affected
// by gravity) and doesn't change icon states, you can just override movement.
// If you want to change how keyboard input is handled or you want to change the
// mob's AI, you can override action() but leave movement() alone.
action(ticks)
#ifdef LIBRARY_DEBUG
if(trace) trace.event("[world.time]: start action:")
#endif
// Calling mob.move_to or mob.move_towards will set either the path
// or destination variables. If either is set, we want to make the
// mob move as those commands specify, not as the keyboard input specifies.
// The follow_path proc is defined in mob-pathing.dm.
if(path || destination)
follow_path()
// if the mob's movement isn't controlled by a call to move_to or
// move_towards, we use the client's keyboard input to control the mob.
else if(client)
// the on_ladder proc determines if we're over a ladder or not.
// the on_ladder var determines if we're actually hanging on it.
if(on_ladder())
if(client.keys[controls.up] || client.keys[controls.down])
if(flying==1)
if(client.keys[controls.up])
vel_y+=1
if(client.keys[controls.down])
vel_y-=1
if(!on_ladder)
vel_y = 0
on_ladder = 1
else
on_ladder = 0
moved = 0
// If we're on a ladder we want the arrow keys to move us in
// all directions. Gravity will not affect you.
if(on_ladder)
if(client.keys[controls.right])
dir = RIGHT
climb(RIGHT)
if(client.keys[controls.left])
dir = LEFT
climb(LEFT)
if(client.keys[controls.up])
climb(UP)
if(client.keys[controls.down])
climb(DOWN)
// If you're not on a ladder, movement is normal.
else
if(client.keys[controls.right])
dir = RIGHT
move(RIGHT)
if(client.keys[controls.left])
dir = LEFT
move(LEFT)
if(client.keys[controls.up])
move(UP)
if(client.keys[controls.down])
move(DOWN)
// by default the jumped var is set to 1 when you press the space bar
if(jumped)
jumped=0
if(can_jump())
jump()
//if(jumping1==0&&jumping2==0&&jumping3==0)
// jumped=0
slow_down()
else
// the slow_down proc will decrease the mob's movement speed if
// they're not pressing the key to move in their current direction.
if(moved)
moved = 0
else
slow_down()
// end of action()
#ifdef LIBRARY_DEBUG
if(trace) trace.event("[world.time]: end action:")
#endif
Random Enemy Code:
Slime
var
rjump=0
njump
icon_state = "slime-standing"
base_state="slime"
pixel_x = -8
pwidth= 16
pheight= 12
fall_speed=1
jump_speed=0.5
hp=20
max_hp=20
move_speed = 1.5
dir = RIGHT
character="enemy"
set_state()
if(dead)
icon_state="slime-dead"
else if(!on_ground)
icon_state="slime-moving"
else if(on_ground)
icon_state="slime-standing"
gravity()
if(!on_ground)
vel_y -= 0.1
jump()
vel_y = 4
spawn(2)
vel_y=4
action()
if(dead) return
if(at_edge())
turn_around()
if(!dead)
for(var/mob/player/p in inside())
if(!dead)
hurt(p)
for(var/mob/player/p in view(10,src))
if(p.y>src.y)
if(src.on_ground)
spawn(4)
if(src.on_ground)
src.jump()
if(p.x>src.x)
src.dir=EAST
if(!on_ground)
src.move(EAST)
if(src.rjump==0)
src.rjump=1
var/whenyagonnamove=rand(1,5)
spawn(whenyagonnamove)
if(on_ground)
src.jump()
src.rjump=0
if(p.x<src.x)
src.dir=WEST
if(!on_ground)
src.move(WEST)
if(src.rjump==0)
src.rjump=1
var/whenyagonnamove=rand(1,5)
spawn(whenyagonnamove)
if(on_ground)
src.jump()
src.rjump=0
if(p.x==src.x&&p.y==src.y)
var/getem=rand(1,4)
if(getem==1)
if(src.on_ground)
src.dir=EAST
if(!on_ground)
src.move(EAST)
if(getem==2)
if(src.on_ground)
src.dir=WEST
if(!on_ground)
src.move(WEST)
if(src.on_ground)
src.jump()
if(p.y<src.y)
if(!on_ground)
if(src.dir==WEST) src.move(WEST)
if(src.dir==EAST) src.move(EAST)
if(on_ground)
spawn(2)
src.jump()
if(src.dropped==0)
src.drop()
spawn(1)
src.dropped=0
for(var/mob/projectile/p in inside())
if(p.enemyweapon==0&&!dead)
if(p.freeze==1)
src.canmove=0
vel_x=0
view(src) << sound('icearrowfreezing.wav', channel=91, volume=150)
src.icon_state="slime-standing"
src.overlays+=/obj/Item_Overlays/Effects/Frozen
spawn(15)
src.canmove=1
view(src) << sound(null, channel=91)
src.overlays-=/obj/Item_Overlays/Effects/Frozen
src.hp-=p.damage
x_damage(src,p.damage,"orangered")
if(src.hp<=0)
src.die()
if(p.freeze==0&&src.dead==0)
var/pow=rand(1,5)
if(pow==1)
src.overlays+=/obj/Item_Overlays/Effects/Attacked/Pow
spawn(4) src.overlays-=/obj/Item_Overlays/Effects/Attacked/Pow
if(pow==2)
src.overlays+=/obj/Item_Overlays/Effects/Attacked/Wam
spawn(4) src.overlays-=/obj/Item_Overlays/Effects/Attacked/Wam
if(pow==3)
src.overlays+=/obj/Item_Overlays/Effects/Attacked/Slam
spawn(4) src.overlays-=/obj/Item_Overlays/Effects/Attacked/Slam
if(pow==4)
src.overlays+=/obj/Item_Overlays/Effects/Attacked/Zap
spawn(4) src.overlays-=/obj/Item_Overlays/Effects/Attacked/Zap
if(pow==5)
src.overlays+=/obj/Item_Overlays/Effects/Attacked/Bam
spawn(4) src.overlays-=/obj/Item_Overlays/Effects/Attacked/Bam
del(p)
..()
Problem description:
I'm using Forum_Account's sidescroller library to handle the movement system in my ongoing project. The action() proc is how I've been handling A.I. With action(), I was able to create a whole dungeon of enemies without experiencing lag problems, although the random layout of the caves has left the cave specific enemies with a more linear player-oriented A.I which lags down the world.cpu once the enemy count gets anything more than low. I'm inexperienced with incorporating world.time, tick_lag, ticks, etc. in A.I. If someone could point me in the right direction, that`d be greatly appreciated.
Off the top of my head, I believe these could be some of the issues:
1. For() isn't using the player list
2. I'm not using nearby() which is a proc to replace view() in the library... I cannot find a way to get this proc to work.
3. The rands constantly being generated
4. The spawns() not incorporating any variables
5. As mentioned previously, I didn't incorporate world.time, tick_lag, ticks, etc.
This may or may not help you, but the best advice I can give you is to make your own system with the help of the developers here. You'll be a lot better off, I think. Good luck.