1 2class TextLog extends RenJS.Plugin { 3 4 log = null; 5 6 text = null; 7 maxLines = 11; 8 9 pageUpBtn = null; 10 pageDownBtn = null; 11 12 currentPage = 0; 13 finalPage = -1; 14 pages = [] 15 16 onInit() { 17 //create log object 18 //create phaser group to hold all graphic elements 19 this.log = this.game.add.group(); 20 this.log.visible = false; 21 //create invisible graphics layer with input enabled so when the log is shown, nothing else in the gui "works" 22 const bgLayer = this.game.add.graphics(); 23 this.log.addChild(bgLayer) 24 bgLayer.beginFill(0xFFFFFF); 25 bgLayer.drawRect(0, 0, this.game.width, this.game.height); 26 bgLayer.endFill(); 27 bgLayer.alpha = 0; 28 bgLayer.inputEnabled = true; 29 30 //create log background centered in the screen 31 const bg = this.game.add.sprite(this.game.world.centerX,20,"logBg"); 32 bg.anchor.set(0.5,0); 33 this.log.addChild(bg); 34 35 //create return button, to close the log 36 const btnY = 415; 37 const returnbtn = this.game.add.button(this.game.world.centerX,btnY,"logReturnBtn",async () => { 38 //hide log with fade (but faster) 39 const fade = this.game.storyConfig.fadetime 40 this.game.storyConfig.fadetime = 150; 41 await this.game.screenEffects.transition.FADEOUT(this.log) 42 this.game.storyConfig.fadetime = fade; 43 44 this.log.visible = false; 45 this.pages = []; 46 this.finalPage = -1; 47 this.currentPage = 0; 48 this.game.unpause(); 49 },this,1,0,1,0,this.log); 50 returnbtn.anchor.set(0.5); 51 52 //create arrow buttons 53 this.pageUpBtn = this.game.add.button(this.game.world.centerX+80,btnY,"arrowBtn",async () => { 54 if (this.currentPage>0){ 55 this.setPage(this.currentPage-1); 56 } 57 58 },this,1,0,1,0,this.log); 59 this.pageUpBtn.anchor.set(0,0.5); 60 this.pageDownBtn = this.game.add.button(this.game.world.centerX-80,btnY,"arrowBtn",async () => { 61 if (this.finalPage==-1 || this.currentPage<this.finalPage){ 62 this.setPage(this.currentPage+1); 63 } 64 },this,1,0,1,0,this.log); 65 this.pageDownBtn.anchor.set(0,0.5); 66 //flip arrow 67 this.pageDownBtn.scale.x = -1; 68 69 // create empty text object where the text will be displayed 70 const style = {...this.game.gui.hud.mBoxes.default.config.text.style}; 71 style.wordWrapWidth = 640; 72 this.text = this.game.add.text(80, 50, "", style); 73 this.log.addChild(this.text); 74 //add new action for the text log button 75 this.game.gui.bindingActions['showTextLog'] = async ()=>{ 76 this.game.world.bringToTop(this.log); 77 this.game.pause(); 78 //update log text, so it will display the last messages first 79 this.setPage(0); 80 81 //show log with fade in (but faster!) 82 this.log.alpha = 0; 83 this.log.visible = true; 84 const fade = this.game.storyConfig.fadetime 85 this.game.storyConfig.fadetime = 150; 86 await this.game.screenEffects.transition.FADEIN(this.log) 87 this.game.storyConfig.fadetime = fade; 88 } 89 90 } 91 92 setPage(page){ 93 this.currentPage = page; 94 if (this.pages.length <= this.currentPage){ 95 if (this.currentPage == 0){ 96 this.buildPage(0); 97 } else { 98 this.buildPage(this.pages[this.currentPage-1].offset); 99 } 100 } 101 //only show page down button if you're NOT on the last page 102 this.pageDownBtn.visible = this.currentPage!=this.finalPage; 103 //only show page up if you're NOT on the first page 104 this.pageUpBtn.visible = this.currentPage!=0; 105 //set page 106 const message = this.game.gui.setTextStyles(this.pages[this.currentPage].message,this.text); 107 this.text.text = message; 108 } 109 110 buildPage(offset){ 111 var lines = 0; 112 let finalRawText = ''; 113 // build the log "page", with a max amount of lines 114 for (var i = this.game.storyLog.length -1 - offset; i>=0; i--){ 115 const entry = this.game.storyLog[i]; 116 var message = entry.message; 117 if (entry.choice){ 118 message = " - "+message; 119 } 120 if (entry.actor){ 121 const name = this.game.managers.character.characters[entry.actor].config.displayName
122 //we'll show the character name in white 123 message = "(color:#ffffff)"+name +":(end) "+message; 124 } 125 //remove any style tag to calculate the wordwrap 126 const finalMessage = this.game.gui.setTextStyles(message,this.text); 127 const messageLines = this.text.precalculateWordWrap(finalMessage) 128 if (messageLines.length + lines > this.maxLines){ 129 //stop adding lines 130 break; 131 } 132 lines+=messageLines.length; 133 // use the raw message text to build the final message, so it will keep the style tags 134 finalRawText = message + '\n' + finalRawText; 135 } 136 // if the index got to the end of the story log, it's the last page 137 if (i==-1){ 138 this.finalPage = this.currentPage; 139 // when you get to the last page, complete the text with empty lines 140 for (var j=0;j<this.maxLines-lines;j++){ 141 finalRawText = '\n' + finalRawText; 142 } 143 } 144 145 this.pages.push({message: finalRawText, offset: this.game.storyLog.length-1 - i}); 146 147 } 148} 149 150RenJSGame.addPlugin('TextLog',TextLog)
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.