I coded a way to read (almost) the entire trial script in the console.

Learn how to use AAO by reading tutorials, and seek help from the AAO community.

Moderator: EN - Forum Moderators

Post Reply
Igniam
Posts: 17
Joined: Fri May 10, 2019 6:31 pm
Spoken languages: English

I coded a way to read (almost) the entire trial script in the console.

Post by Igniam »

I was looking for a way to read a game's script but the editor mode is slow, so I made this instead, which is code you can paste in the console and it will output each line with colors. It doesn't contain cross-examinations, though.

If you don't know how to access the console, right click on some blank spot on the trial page, click "Inspect", change the tab of the window to "Console" and paste all the code in and press Enter.

What it should look like:

Image

Code: Select all

// Text copier 3 with colors added.
function colormark(text) {return text.replace(/#\/instant/g, "#/colour").split(/\[#\/colour:.*?\]|\[\/#]/s).join("%c")} // "s" makes dots match newline
function findcolors(text) {return text.replace(/#\/instant/g, "#/colour").match(/\[#\/colour:.*?\].*?\[\/#]/s) ? text.replace(/#\/instant/g, "#/colour").replace(/#\/instant/g, "#/colour").match(/\[#\/colour:.*?\].*?\[\/#]/gs).map(i => 'color: ' + i.match(/colour:(.*?)\]/s)[1]) : []}
var lookup = trial_data.profiles.map(x => x!=0? x.short_name : "")
var merged_with_prev = false
var showindex = true

var rv = []; var rvcolors = []
for (let i = 1; i < trial_data.frames.length; i++) {
  let x = trial_data.frames[i]; let speaker = ""; let newline = `\n`; let colors = [];

  colors = colors.concat(findcolors(x.text_content))
  let text = colormark(x.text_content) ? colormark(x.text_content).replace(/\[#.*?\]/gi, "").replace(/\[#\]/g, "") : ""

  let green_transition = (x.text_colour == "#00F61C" || x.text_colour == "lime") && ((x.speaker_id == -3 && x.speaker_voice == -3) || x.place != 0)
  if (!green_transition) {text = text.replace(/\n/g, " ")}
  if (text == "") {continue}

  function insert_between (array, element) {return array.reduce((r, a) => r.concat(a, element), [element])}
  if (x.text_colour == "red") {text = `%c${text}`; colors = insert_between(colors, "color: red")}
  else if (green_transition) {text = `%c${text}`; colors = insert_between(colors, 'color: #00F61C; background: black; display: block')}
  else if (x.text_colour != "white") {text = `%c${text}`; colors = insert_between(colors, `color: ${x.text_colour}`)}
  else if (x.text_colour == "white" && colormark(x.text_content)) {colors = insert_between(colors, `color: ${x.text_colour}`).slice(1)} // if there's any color modifiers but base is white

  if (x.speaker_id > 0 && !merged_with_prev) {
    speaker = `%c${x.speaker_name}%c: `
    if (x.speaker_name == "") {
      speaker = `%c${lookup[x.speaker_id]}%c: `
    }
    colors = [`color: white; background: darkblue; font-weight: bold; border-radius: 2px; padding-left: 3px; padding-right: 1px; padding-top: 1px; padding-bottom: 1px`, `color: white`].concat(colors)
  }
  if (merged_with_prev) {
    rv[rv.length-1] += text; rvcolors[rvcolors.length-1] = rvcolors[rvcolors.length-1].concat(colors)
    if (x.merged_to_next) {merged_with_prev = true} else {
      merged_with_prev = false
      console.log(rv[rv.length-1], ...rvcolors[rvcolors.length-1])
    } // Set for next frame
    continue
  }
  if (x.merged_to_next) {merged_with_prev = true} else {merged_with_prev = false} // Set for next frame
  text = text.replace(/ +/g, " ")
  rv.push(`${showindex? `${i} `:""}${speaker}${text}`)
  rvcolors.push(colors)
  if (!x.merged_to_next) {
    console.log(rv[rv.length-1], ...rvcolors[rvcolors.length-1])
  }
} /* code written by main_gi to read AAO trials */
Here is a minified version that takes up a little less console space.

Code: Select all

function colormark(e){return e.replace(/#\/instant/g,"#/colour").split(/\[#\/colour:.*?\]|\[\/#]/s).join("%c")}function findcolors(e){return e.replace(/#\/instant/g,"#/colour").match(/\[#\/colour:.*?\].*?\[\/#]/s)?e.replace(/#\/instant/g,"#/colour").replace(/#\/instant/g,"#/colour").match(/\[#\/colour:.*?\].*?\[\/#]/gs).map(e=>"color: "+e.match(/colour:(.*?)\]/s)[1]):[]}var lookup=trial_data.profiles.map(e=>0!=e?e.short_name:""),merged_with_prev=!1,showindex=!0,rv=[],rvcolors=[];for(let e=1;e<trial_data.frames.length;e++){let r=trial_data.frames[e],o="",t=[];t=t.concat(findcolors(r.text_content));let c=colormark(r.text_content)?colormark(r.text_content).replace(/\[#.*?\]/gi,"").replace(/\[#\]/g,""):"",l=("#00F61C"==r.text_colour||"lime"==r.text_colour)&&(-3==r.speaker_id&&-3==r.speaker_voice||0!=r.place);function insert_between(e,r){return e.reduce((e,o)=>e.concat(o,r),[r])}l||(c=c.replace(/\n/g," ")),""!=c&&("red"==r.text_colour?(c=`%c${c}`,t=insert_between(t,"color: red")):l?(c=`%c${c}`,t=insert_between(t,"color: #00F61C; background: black; display: block")):"white"!=r.text_colour?(c=`%c${c}`,t=insert_between(t,`color: ${r.text_colour}`)):"white"==r.text_colour&&colormark(r.text_content)&&(t=insert_between(t,`color: ${r.text_colour}`).slice(1)),r.speaker_id>0&&!merged_with_prev&&(o=`%c${r.speaker_name}%c: `,""==r.speaker_name&&(o=`%c${lookup[r.speaker_id]}%c: `),t=["color: white; background: darkblue; font-weight: bold; border-radius: 2px; padding-left: 3px; padding-right: 1px; padding-top: 1px; padding-bottom: 1px","color: white"].concat(t)),merged_with_prev?(rv[rv.length-1]+=c,rvcolors[rvcolors.length-1]=rvcolors[rvcolors.length-1].concat(t),r.merged_to_next?merged_with_prev=!0:(merged_with_prev=!1,console.log(rv[rv.length-1],...rvcolors[rvcolors.length-1]))):(merged_with_prev=!!r.merged_to_next,c=c.replace(/ +/g," "),rv.push(`${showindex?`${e} `:""}${o}${c}`),rvcolors.push(t),r.merged_to_next||console.log(rv[rv.length-1],...rvcolors[rvcolors.length-1])))}
Edit: Fixed a small bug with 'undefined' names.
Last edited by Igniam on Mon Feb 01, 2021 2:16 pm, edited 1 time in total.
User avatar
SuperAj3
Posts: 1309
Joined: Wed Sep 01, 2010 11:19 am
Spoken languages: English, 日本語(少しだけ)
Location: Legal Land

Re: I coded a way to read (almost) the entire trial script in the console.

Post by SuperAj3 »

That’s cool! I tried it out and it worked! And yeah for some reason it showed different character names for the CE dialogue, but I guess it can't be helped.

I’m just trying to think of the purpose for this. Basically you can already read the script by playing the case, or just viewing the storyboard in the editor. Is this more a time saving thing to not have to play?
ImageImageImageImage
Avatar from the TSub website :april:
Igniam
Posts: 17
Joined: Fri May 10, 2019 6:31 pm
Spoken languages: English

Re: I coded a way to read (almost) the entire trial script in the console.

Post by Igniam »

I coded this more as a replaying-rereading thing. I recently played Turnabout Daybreak, which doesn't give the answer in the same trial but expects the player to think of a theory given all the evidence, and so this kind of thing really helps to look over the plot instead of having to click repeatedly to reread. I definitely wouldn't recommend using it *instead of* actually playing a trial of course, also you wouldn't get to read evidence and profiles that way.
User avatar
SuperAj3
Posts: 1309
Joined: Wed Sep 01, 2010 11:19 am
Spoken languages: English, 日本語(少しだけ)
Location: Legal Land

Re: I coded a way to read (almost) the entire trial script in the console.

Post by SuperAj3 »

Igniam wrote: Mon Jan 25, 2021 2:06 am I coded this more as a replaying-rereading thing. I recently played Turnabout Daybreak, which doesn't give the answer in the same trial but expects the player to think of a theory given all the evidence, and so this kind of thing really helps to look over the plot instead of having to click repeatedly to reread. I definitely wouldn't recommend using it *instead of* actually playing a trial of course, also you wouldn't get to read evidence and profiles that way.
Ahh I get you!
It can also work as a neat 'text log' alternative if you've accidently skipped text (which I do sometimes if I click twice).
ImageImageImageImage
Avatar from the TSub website :april:
broseph
Posts: 1
Joined: Sat Nov 15, 2014 6:37 pm
Gender: Male
Spoken languages: English

Re: I coded a way to read (almost) the entire trial script in the console.

Post by broseph »

What game was that excerpt from?
User avatar
Enthalpy
Community Manager
Posts: 5169
Joined: Wed Jan 04, 2012 4:40 am
Gender: Male
Spoken languages: English, limited Spanish

Re: I coded a way to read (almost) the entire trial script in the console.

Post by Enthalpy »

Thank you for making this. It's currently saving me quite a bit of effort as I'm speed-reading for QA purposes.
[D]isordered speech is not so much injury to the lips that give it forth, as to the disproportion and incoherence of things in themselves, so negligently expressed. ~ Ben Jonson
User avatar
Enthalpy
Community Manager
Posts: 5169
Joined: Wed Jan 04, 2012 4:40 am
Gender: Male
Spoken languages: English, limited Spanish

Re: I coded a way to read (almost) the entire trial script in the console.

Post by Enthalpy »

The script is bugged. Replace the line that defines lookup with

Code: Select all

var lookup = Object.fromEntries(trial_data.profiles.map(x => [x.id, x!=0? x.short_name : ""]))
Old code mapped index to name. New code maps id to name.
[D]isordered speech is not so much injury to the lips that give it forth, as to the disproportion and incoherence of things in themselves, so negligently expressed. ~ Ben Jonson
Post Reply