First off, you'll want to change true
to false in your AddEntityCollideCallback line. The true signifies that the callback will be removed once triggered, meaning your function will run only once. Changing it to false lets the callback run each time the collision happens, so that once the player returns to the hallway with the hammer, the function will run again.
Secondly, this semantics bug is likely stemming from a map cache issue. I see nothing wrong syntactically nor semantically in your code. Try adding some debug messages to see (visually) the value of HasItem("stone_hammer_1"). Do something like AddDebugMessage("does player have hammer: "+HasItem("stone_hammer_1"), false);
Thirdly, if you want to do this a different way, you can leave true
as is, and simply add the collision callback after the player picks up the hammer. This is a simple way to bypass the conditional and at the same time take advantage of the auto-remove feature of collision callbacks, so you don't have to remove it manually.
To do this, create a function called HammerPick or something similar. Next, select your hammer item in the level editor. Go to the second tab, and in the PlayerInteractCallback field write HammerPick. The function takes one parameter, a string. Then just stick the AddEntityCollideCallback line in that function, and you can totally disregard your if statement in CollideActivateLiveGrunt function.
void HammerPick(string &in hammerRef)
//just an example to show you the parameter
Off to MW3~!