]> git.xonotic.org Git - xonotic/xonotic.git/blobdiff - misc/tools/midi2cfg-ng.pl
use jumpers for a test
[xonotic/xonotic.git] / misc / tools / midi2cfg-ng.pl
index fad3a4e1028a5ff92d10bfb35da0fb1130dcbd45..3e178a24d3463aab4e021da807f0d16d541799f6 100755 (executable)
@@ -24,6 +24,7 @@ my $timeoffset_predone = 2;
 my $timeoffset_postdone = 2;
 my $timeoffset_preintermission = 2;
 my $timeoffset_postintermission = 2;
+my $time_forgetfulness = 1.5;
 
 my ($config, @midilist) = @ARGV;
 
@@ -202,6 +203,10 @@ sub botconfig_read($)
                {
                        $timeoffset_postintermission = $1;
                }
+               elsif(/^time_forgetfulness (.*)/)
+               {
+                       $time_forgetfulness = $1;
+               }
                else
                {
                        print "unknown command: $_\n";
@@ -341,6 +346,7 @@ sub busybot_cmd_bot_execute($$@)
                {
                        $commands .= sprintf "sv_cmd bot_cmd %d barrier\n", $bot->{id};
                        $bot->{timer} = $bot->{busytimer} = 0;
+                       undef $bot->{lastuse};
                }
                elsif($_->[0] eq 'raw')
                {
@@ -466,6 +472,21 @@ sub busybot_note_on_bot($$$$$$$)
                $bot->{busy} = [$channel, $note, $cmds_off];
        }
        ++$bot->{seen}{$k0}{$k1};
+
+       if(($bot->{lastuse} // -666) >= $time - $time_forgetfulness && $channel == $bot->{lastchannel})
+       {
+               $bot->{lastchannelsequence} += 1;
+       }
+       else
+       {
+               $bot->{lastchannelsequence} = 1;
+       }
+       $bot->{lastuse} = $time;
+       $bot->{lastchannel} = $channel;
+
+#      print STDERR "$time $bot->{id} $channel:$note\n"
+#              if $channel == 11;
+
        return 1;
 }
 
@@ -499,6 +520,45 @@ sub busybot_note_off($$$)
        return 0;
 }
 
+sub botsort($$$$@)
+{
+       my ($time, $channel, $program, $note, @bots) = @_;
+       return
+               map
+               {
+                       $_->[0]
+               }
+               sort
+               {
+                       $b->[1] <=> $a->[1]
+                       or
+                       ($a->[0]->{lastuse} // -666) <=> ($b->[0]->{lastuse} // -666)
+                       or
+                       $a->[2] <=> $b->[2]
+               }
+               map
+               {
+                       my $q = 0;
+                       if($channel != 10) # percussion just should do round robin
+                       {
+                               if(($_->{lastuse} // -666) >= $time - $time_forgetfulness)
+                               {
+                                       if($channel == $_->{lastchannel})
+                                       {
+                                               $q += $_->{lastchannelsequence};
+                                       }
+                                       else
+                                       {
+                                               # better leave this one alone
+                                               $q -= $_->{lastchannelsequence};
+                                       }
+                               }
+                       }
+                       [$_, $q, rand]
+               }
+               @bots;
+}
+
 sub busybot_note_on($$$$)
 {
        my ($time, $channel, $program, $note) = @_;
@@ -514,7 +574,7 @@ sub busybot_note_on($$$$)
 
        my @epicfailbots = ();
 
-       for(unsort @busybots_allocated)
+       for(botsort $time, $channel, $program, $note, @busybots_allocated)
        {
                my $canplay = busybot_note_on_bot $_, $time, $channel, $program, $note, 0, 0;
                if($canplay > 0)
@@ -754,7 +814,7 @@ sub ConvertMIDI($$)
                        if($midinotes{$chan}{$_->[5]})
                        {
                                --$notes_stuck;
-                               busybot_note_off($t - SYS_TICRATE, $chan, $_->[5]);
+                               busybot_note_off($t - SYS_TICRATE - 0.001, $chan, $_->[5]);
                        }
                        busybot_note_on($t, $chan, $programs{$chan} || 1, $_->[5]);
                        ++$notes_stuck;
@@ -766,7 +826,7 @@ sub ConvertMIDI($$)
                        if($midinotes{$chan}{$_->[5]})
                        {
                                --$notes_stuck;
-                               busybot_note_off($t - SYS_TICRATE, $chan, $_->[5]);
+                               busybot_note_off($t - SYS_TICRATE - 0.001, $chan, $_->[5]);
                        }
                        $midinotes{$chan}{$_->[5]} = 0;
                }
@@ -797,7 +857,7 @@ sub ConvertMIDI($$)
                                        my $votehigh = 0;
                                        my $votelow = 0;
                                        my $votegood = 0;
-                                       for(@busybots_allocated)
+                                       for(@busybots_allocated, grep { $_->{count} > 0 } values %$busybots)
                                        {
                                                next # I won't play on this channel
                                                        if defined $_->{channels} and not $_->{channels}->{$channel};
@@ -933,6 +993,8 @@ for(;;)
                my @preallocate_new = map { $_->{classname} } @busybots_allocated;
                if(@preallocate_new == @preallocate)
                {
+                       print "sv_cmd bot_cmd reset\n";
+                       print "sv_cmd bot_cmd setbots @{[scalar @preallocate_new]}\n";
                        print "$precommands$commands";
                        exit 0;
                }