- # Check if the action should be blocked
- my $strongkill = $type eq ACT_KILL && $args{strong};
- my $roleblocked = $tplayers{$source}{roleblocked};
- my $hidden = $tplayers{$target}{hidden};
- my $hidepierce = $args{hidepierce};
- if ($source && (( $roleblocked && !$strongkill ) || ($hidden && !$hidepierce) )) {
- msg MSG_NORESULT, %args if $type ~~ INVESTIGATIVE_ACTIONS;
- return
- }
- }
-
-
- given ($type) {
- when(ACT_KILL) {
- break if $tplayers{$target}{bulletproof} && defined $source;
- if ($tplayers{$target}{guard_count} && defined $source) {
- $tplayers{$target}{guard_count}--;
- # Copy this action to the first guard
- $args{target} = shift $tplayers{$target}{guards};
- @_ = ($type, %args);
- goto &doaction;
- }
- if ($tplayers{$target}{protection} && !$args{strong}) {
- $tplayers{$target}{protection}--;
- break
- }
- msg MSG_DEATH, %args;
- delete $players{$target}
- }
-
- when(ACT_LYNCH){
- if ($tplayers{$target}{guard_count}) {
- $tplayers{$target}{guard_count}--;
- $args{target} = shift $tplayers{$target}{guards};
- $target=$args{target};
- }
- if ($tplayers{$target}{protection}) {
- $tplayers{$target}{protection}--;
- break
- }
- msg MSG_DEATH, %args, reason => 'lynched';
- delete $players{$target}
- }
-
- when(ACT_PROTECT){
- my $count = $args{count} // 1;
- $tplayers{$target}{protection} += $count unless $tplayers{$target}{macho}
- }
-
- when(ACT_ROLEBLOCK){
- $tplayers{$target}{roleblocked} = 1
- }
-
- when(ACT_GUNCHECK){
- my $role = $players{$target}{role};
- my $hasgun = $role ~~ GUNROLES || ($players{$target}{faction} eq mafia && $role ne doctor);
- msg MSG_GUNCHECK, %args, result => $hasgun
- }
-
- when(ACT_TRACK_RESULT){
- msg MSG_TRACK, %args, result => [ uniq @{$tplayers{$target}{targets} // []} ];
- }
-
- when(ACT_WATCH_RESULT){
- msg MSG_WATCH, %args, result => [ uniq @{$tplayers{$target}{sources} // []} ];
- }
-
- when(ACT_GUARD){
- $tplayers{$target}{guard_count}++;
- $tplayers{$target}{guards} //= [];
- push $tplayers{$target}{guards}, $source;
- }
-
- when(ACT_ROLECOP){
- my $result = $players{$target}{role};
- $result = vanilla if $result eq goon;
- msg MSG_ROLECOP, %args, result => ucfirst $result
- }
-
- when(ACT_COP){
- my $result = $players{$target}{faction} eq mafia;
- $result = 1 if $players{$target}{miller};
- $result = 0 if $players{$target}{godfather};
- msg MSG_COP, %args, result => $result
- }
-
- when(ACT_HIDE){
- $tplayers{$source}{hidden} = 1;
- $tplayers{$target}{hiders} //= [];
- push $tplayers{$target}{hiders}, $source
- }
- }
+ my %act_lut = (
+ ACT_KILL => sub {
+ break if $tplayers{$target}{bulletproof} && defined $source;
+ if ($tplayers{$target}{guard_count} && defined $source) {
+ $tplayers{$target}{guard_count}--;
+ # Copy this action to the first guard
+ $args{target} = shift @{$tplayers{$target}{guards}};
+ @_ = ($type, %args);
+ goto &doaction;
+ }
+ if ($tplayers{$target}{protection} && !$args{strong}) {
+ $tplayers{$target}{protection}--;
+ break
+ }
+ msg MSG_DEATH, %args;
+ delete $players{$target}
+ },
+
+ ACT_LYNCH => sub {
+ if ($tplayers{$target}{guard_count}) {
+ $tplayers{$target}{guard_count}--;
+ $args{target} = shift @{$tplayers{$target}{guards}};
+ $target=$args{target};
+ }
+ if ($tplayers{$target}{protection}) {
+ $tplayers{$target}{protection}--;
+ break
+ }
+ msg MSG_DEATH, %args, reason => 'lynched';
+ delete $players{$target}
+ },
+
+ ACT_PROTECT => sub {
+ my $count = $args{count} // 1;
+ $tplayers{$target}{protection} += $count unless $tplayers{$target}{macho}
+ },
+
+ ACT_ROLEBLOCK => sub {
+ $tplayers{$target}{roleblocked} = 1
+ },
+
+ ACT_GUNCHECK => sub {
+ my $role = $players{$target}{role};
+ my $hasgun = $GUNROLES_HASH{$role} || ($players{$target}{faction} eq mafia && $role ne doctor);
+ msg MSG_GUNCHECK, %args, result => $hasgun
+ },
+
+ ACT_TRACK_RESULT => sub {
+ msg MSG_TRACK, %args, result => [ uniq @{$tplayers{$target}{targets} // []} ];
+ },
+
+ ACT_WATCH_RESULT => sub {
+ msg MSG_WATCH, %args, result => [ uniq @{$tplayers{$target}{sources} // []} ];
+ },
+
+ ACT_GUARD => sub {
+ $tplayers{$target}{guard_count}++;
+ $tplayers{$target}{guards} //= [];
+ push @{$tplayers{$target}{guards}}, $source;
+ },
+
+ ACT_ROLECOP => sub {
+ my $result = $players{$target}{role};
+ $result = vanilla if $result eq goon;
+ msg MSG_ROLECOP, %args, result => ucfirst $result
+ },
+
+ ACT_COP => sub {
+ my $result = $players{$target}{faction} eq mafia;
+ $result = 1 if $players{$target}{miller};
+ $result = 0 if $players{$target}{godfather};
+ msg MSG_COP, %args, result => $result
+ },
+
+ ACT_HIDE => sub {
+ $tplayers{$source}{hidden} = 1;
+ $tplayers{$target}{hiders} //= [];
+ push @{$tplayers{$target}{hiders}}, $source
+ },
+ );
+
+ $act_lut{$type}->();