No compile issues. No run-time issues.
Players should be able to only block the mob infront of you.
My character is able to block from the sides or the back, it's crazy it's like he's Neo from the Matrix.
Extra Info:
The system uses q() + dir to block W/A/S/D directions.
A high block (Up) would block D(DownSlash),etc.
Defense has 50% automation (i.e you can block 2 directions with 1 button).
Code:
//Action States, Defense. :#defines:
#define DEFLECT_N 1 // 0001
#define DEFLECT_S 2 // 0010
#define DEFLECT_E 4 // 0100
#define DEFLECT_W 8 // 1000
#define DEFEND 15 // 1111
//Blocking System :mob/player:
// toggle defending
start_defending()
if (state != STATE_NORMAL) return
else
state = DEFEND
old_state = icon_state
icon_state = "[icon_state] block"
stop_defending()
if (is_defending() )
state = STATE_NORMAL
icon_state = old_state
//checks if they're defending
is_defending()
world << output("Observing: [Attacker] from [Attack_In_Sight] is attacking [src] who is looking [src.dir]","output")
return is_deflecting() //call deflecting proc
is_deflecting(direction = DEFEND) //checks if they're deflecting
return state & direction //checks if they're deflecting specifically
//Override Move Proc
Move(newLoc, moveDir)
if(can_move)
if(state in list(STATE_NORMAL,STATE_RUNNING, KNOCK_BACK)) //havent needed it yet
if(world.time - move_delay >= last_move || moveDir != last_dir)
. = ..()
if(.)
last_move = world.time
last_dir = moveDir
else if(state == STRUGGLE)
var/oldDir = src.dir
. = ..()
src.dir = oldDir
// moveDir = 4 //EAST is what this would be set to if they are moving EAST
else if(is_defending() ) // they're defending
if(state & moveDir) return 0 //ATTACK's & DEFLECT's are linked to the same bit numbers. so in this SPECIFIC case means,
//if they are already blocking in the direction they are trying to then it doesnt need to be set. I see.
state &= ~DEFEND
state |= (moveDir & (moveDir-1)) //the deflections are 1, 2, 4, 8 (cardinal directions)
icon_state = getBlockState(moveDir)
//etc
getBlockState(d)
var/prefix = is_sheathed() ? "sheath_" : "unsheath_"
return "[prefix][dir2combatText(d)] block"
is_sheathed()
return (stance & (STANCE_NORMAL | STANCE_SWORD_SHEATHED))
proc/dir2combatText(d) :proc:
switch(d)
if(NORTH) return "high"
if(SOUTH) return "low"
if(EAST) return "right"
if(WEST) return "left"
//Offense & etc :mob/player:
attackloop(var/mob/target)
while(target && attack(target))
sleep(1)
attack(var/mob/player/victim)
victim = victim || locate(/mob) in get_step(src,src.dir)
if(!victim) return 0
var/attackDamage = basedamage //prime.execution
var/isBlocking = victim.auto_block(src.attack)
if(isBlocking)
if(victim.is_beside(src)) return
var/effect/symbols/block_party = new(src); flick("block_party", block_party)
attackDamage /= 2
victim.icon_state = "[victim.getBlockState(isBlocking)]"
world << output("blocked [dir2combatText(src.attack)] with [dir2combatText(victim.is_defending())]","output")
return
if(stance == STANCE_SWORD_UNSHEATHED) //sets up condition secondary execution
apply_PowerUps()
attackDamage = damage //condition & damage calc set up
victim.take_damage(attackDamage, src) //execution halted and damage calc overridden in/if block_left()
victim << output("You take [attackDamage] damage! from [src].","output2")
src << output("You hit [victim] for [attackDamage]!","output2")
take_damage(damage, atom/source)
health = max(health - damage, 0)
world << output("Fighting!: [damage] done should match [source]","output2")
if(src.client) src.client.hud.refreshHPBars()
death_check(source)
//are you still here?
apply_PowerUps()
var/item/sword/sword = new /item/sword
world << output("[src]","output2")
src.damage = sword.weapon_damage + src.basedamage
world << output("[damage] = [sword.weapon_damage] and [basedamage]","output2")
auto_block(var/attackDir,attacker) //automation detector
var/blockDir = is_defending()
if(blockDir == DEFEND) return //FIX for phantom bug
world << output("attackDir[attackDir] && blockDir[blockDir]","output2")
return (blockDir) ? attackDir & (blockDir | turn(blockDir, 180)) : 0
Debug:
// if(!blockDir == locate(/mob) in get_step(src,src.dir)) return in "autoblock"
// if(src.is_beside()) return
// if(!Attacker in get_step(src,src.dir)) return in "is_defend()"
// :mob/player:
is_beside(var/mob/M)
return (get_dir(M, src) == turn(M.dir, 90) || get_dir(M, src) == turn(M.dir, -90) )
Will not work.