-sub doaction {
- my ($type, $args) = @_;
- my %args = %$args;
- my $source = $args{source};
- my $target = $args{target};
- if (defined $source && defined $target) {
- # Watcher and tracker variables
- $tplayers{$source}{targets} //= [];
- push $tplayers{$source}{targets}, $target;
- $tplayers{$target}{sources} //= [];
- push $tplayers{$target}{sources}, $source;
-
- # Copy this action to everybody hiding behind $target
- if (exists $tplayers{$target}{hiders}) {
- for my $target (@{$tplayers{$target}{hiders}}) {
- my %args = %args;
- $args{target} = $target;
- $args{hidepierce} = 1;
- doaction($type, \%args);
- }
- }
-
- # 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