Add chat history #100
|
@ -3,7 +3,7 @@
|
|||
#include <symbols/minecraft.h>
|
||||
|
||||
struct TextInputBox {
|
||||
static TextInputBox *create(const std::string &placeholder = "", const std::string &text = "", const std::vector<std::string> *history = NULL);
|
||||
static TextInputBox *create(const std::string &placeholder = "", const std::string &text = "");
|
||||
bigjango13 marked this conversation as resolved
Outdated
|
||||
|
||||
GuiComponent super;
|
||||
|
||||
|
@ -18,11 +18,10 @@ struct TextInputBox {
|
|||
void onClick(int x, int y);
|
||||
bool clicked(int x, int y);
|
||||
std::string getText();
|
||||
void setText(std::string text);
|
||||
bool isFocused();
|
||||
void setMaxLength(int max_length);
|
||||
|
||||
int history_pos;
|
||||
|
||||
private:
|
||||
void recalculateScroll();
|
||||
|
||||
|
@ -40,5 +39,4 @@ private:
|
|||
Font *m_pFont;
|
||||
int m_maxLength;
|
||||
int m_scrollPos;
|
||||
const std::vector<std::string> *history;
|
||||
};
|
||||
|
|
|
@ -15,11 +15,16 @@ static std::vector<std::string> &get_history() {
|
|||
return history;
|
||||
}
|
||||
|
||||
static std::string index_vec(const std::vector<std::string> &vec, int pos) {
|
||||
return pos == int(vec.size()) ? "" : vec.at(pos);
|
||||
}
|
||||
|
||||
// Structure
|
||||
struct ChatScreen {
|
||||
TextInputScreen super;
|
||||
TextInputBox *chat;
|
||||
Button *send;
|
||||
int history_pos;
|
||||
};
|
||||
CUSTOM_VTABLE(chat_screen, Screen) {
|
||||
TextInputScreen::setup(vtable);
|
||||
|
@ -29,10 +34,11 @@ CUSTOM_VTABLE(chat_screen, Screen) {
|
|||
original_init(super);
|
||||
ChatScreen *self = (ChatScreen *) super;
|
||||
// Text Input
|
||||
self->chat = TextInputBox::create("", "", &get_history());
|
||||
self->chat = TextInputBox::create();
|
||||
self->super.m_textInputs->push_back(self->chat);
|
||||
self->chat->init(super->font);
|
||||
self->chat->setFocused(true);
|
||||
self->history_pos = get_history().size();
|
||||
// Determine Max Length
|
||||
std::string prefix = _chat_get_prefix(Strings_default_username);
|
||||
int max_length = MAX_CHAT_MESSAGE_LENGTH - prefix.length();
|
||||
|
@ -91,6 +97,24 @@ CUSTOM_VTABLE(chat_screen, Screen) {
|
|||
_chat_queue_message(text.c_str());
|
||||
}
|
||||
Minecraft_setScreen(super->minecraft, NULL);
|
||||
} else if (key == 0x26 && self->chat->isFocused()) {
|
||||
// Up
|
||||
int old_pos = self->history_pos;
|
||||
self->history_pos -= 1;
|
||||
if (self->history_pos < 0) self->history_pos = get_history().size();
|
||||
if (old_pos != self->history_pos) {
|
||||
self->chat->setText(index_vec(get_history(), self->history_pos));
|
||||
bigjango13 marked this conversation as resolved
TheBrokenRail
commented
Is this check needed? Because if Is this check needed? Because if `old_pos == self->history_pos`, wouldn't that just call `setText` with the current text, doing nothing?
bigjango13
commented
Yep, that's left over. Yep, that's left over.
|
||||
}
|
||||
return;
|
||||
} else if (key == 0x28 && self->chat->isFocused()) {
|
||||
// Down
|
||||
int old_pos = self->history_pos;
|
||||
self->history_pos += 1;
|
||||
if (self->history_pos > int(get_history().size())) self->history_pos = 0;
|
||||
if (old_pos != self->history_pos) {
|
||||
self->chat->setText(index_vec(get_history(), self->history_pos));
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Call Original Method
|
||||
original_keyPressed(super, key);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
// Death Messages
|
||||
static const char *monster_names[] = {"Zombie", "Creeper", "Skeleton", "Spider", "Zombie Pigman"};
|
||||
static std::string get_death_message(Player *player, Entity *cause, bool was_shot = false) {
|
||||
std::string get_death_message(Player *player, Entity *cause, bool was_shot = false) {
|
||||
// Prepare Death Message
|
||||
std::string message = player->username;
|
||||
if (cause) {
|
||||
|
|
|
@ -2,16 +2,7 @@
|
|||
|
||||
#include <mods/text-input-box/TextInputBox.h>
|
||||
|
||||
static int get_vec_size(const std::vector<std::string> *vec) {
|
||||
return vec ? vec->size() : 0;
|
||||
}
|
||||
|
||||
static std::string index_vec(const std::vector<std::string> *vec, int pos) {
|
||||
if (vec == NULL || pos == get_vec_size(vec)) return "";
|
||||
return vec->at(pos);
|
||||
}
|
||||
|
||||
TextInputBox *TextInputBox::create(const std::string &placeholder, const std::string &text, const std::vector<std::string> *history) {
|
||||
TextInputBox *TextInputBox::create(const std::string &placeholder, const std::string &text) {
|
||||
// Construct
|
||||
TextInputBox *self = new TextInputBox;
|
||||
GuiComponent_constructor(&self->super);
|
||||
|
@ -31,8 +22,6 @@ TextInputBox *TextInputBox::create(const std::string &placeholder, const std::st
|
|||
self->m_pFont = nullptr;
|
||||
self->m_maxLength = -1;
|
||||
self->m_scrollPos = 0;
|
||||
self->history = history;
|
||||
self->history_pos = get_vec_size(history);
|
||||
|
||||
// Return
|
||||
return self;
|
||||
|
@ -99,16 +88,6 @@ void TextInputBox::keyPressed(int key) {
|
|||
recalculateScroll();
|
||||
break;
|
||||
}
|
||||
case 0x26: {
|
||||
// Up
|
||||
int old_pos = history_pos;
|
||||
history_pos -= 1;
|
||||
if (history_pos < 0) history_pos = get_vec_size(history);
|
||||
if (old_pos == history_pos) break;
|
||||
m_text = index_vec(history, history_pos);
|
||||
m_insertHead = int(m_text.size());
|
||||
break;
|
||||
}
|
||||
case 0x27: {
|
||||
// Right
|
||||
m_insertHead++;
|
||||
|
@ -122,16 +101,6 @@ void TextInputBox::keyPressed(int key) {
|
|||
recalculateScroll();
|
||||
break;
|
||||
}
|
||||
case 0x28: {
|
||||
// Down
|
||||
int old_pos = history_pos;
|
||||
history_pos += 1;
|
||||
if (history_pos > get_vec_size(history)) history_pos = 0;
|
||||
if (old_pos == history_pos) break;
|
||||
m_text = index_vec(history, history_pos);
|
||||
m_insertHead = int(m_text.size());
|
||||
break;
|
||||
}
|
||||
case 0x0d: {
|
||||
// Enter
|
||||
m_bFocused = false;
|
||||
|
@ -316,6 +285,11 @@ std::string TextInputBox::getText() {
|
|||
return m_text;
|
||||
}
|
||||
|
||||
void TextInputBox::setText(std::string str) {
|
||||
m_text = str;
|
||||
m_insertHead = int(m_text.size());
|
||||
}
|
||||
|
||||
bool TextInputBox::isFocused() {
|
||||
return m_bFocused;
|
||||
}
|
||||
|
|
|
@ -6,4 +6,4 @@ property Minecraft *mc = 0x18;
|
|||
method void renderItem(Mob *mob, ItemInstance *item) = 0x4b824;
|
||||
method void render(float param_1) = 0x4bfcc;
|
||||
|
||||
static-property ItemInHandRenderer *instance = 0x137bc0;
|
||||
static-property ItemInHandRenderer **instance = 0x137bc0;
|
||||
bigjango13 marked this conversation as resolved
Outdated
TheBrokenRail
commented
This seems wrong. I think this address actually refers to an
This seems wrong. I think this address actually refers to an `EntityRenderDispatcher`. Which then has a first property of `ItemInHandRenderer`.
```c++
this_00 = (ItemInHandRenderer *)operator.new(0x70dc);
ItemInHandRenderer::ItemInHandRenderer(this_00,param_1);
this->field0_0x0 = this_00;
ppIVar1 = (ItemInHandRenderer **)EntityRenderDispatcher::getInstance();
*ppIVar1 = this->field0_0x0;
```
TheBrokenRail
commented
Yup, it's Yup, it's `EntityRenderer::entityRenderDispatcher`.
|
|
@ -4,5 +4,6 @@ method void colorABGR(int color) = 0x52b54;
|
|||
method void color(int r, int g, int b, int a) = 0x52a48;
|
||||
method void vertex(float x, float y, float z) = 052bc0;
|
||||
method void vertexUV(float x, float y, float z, float u, float v) = 0x52d40;
|
||||
method void addOffset(float x, float y, float z) = 0x52d90;
|
||||
|
||||
static-property Tesselator instance = 0x137538;
|
||||
|
|
|
@ -23,6 +23,8 @@ virtual-method void tick(Level *level, int x, int y, int z) = 0x58;
|
|||
virtual-method void neighborChanged(Level *level, int x, int y, int z, int neighborId) = 0x64;
|
||||
virtual-method void onPlace(Level *level, int x, int y, int z) = 0x68;
|
||||
virtual-method void onRemove(Level *level, int x, int y, int z) = 0x6c;
|
||||
virtual-method int getResource(int data, Random *random) = 0x70;
|
||||
virtual-method int getResourceCount(Random *random) = 0x74;
|
||||
virtual-method int getRenderLayer() = 0x94;
|
||||
virtual-method int use(Level *level, int x, int y, int z, Player *player) = 0x98;
|
||||
virtual-method void setPlacedBy(Level *level, int x, int y, int z, Mob *placer) = 0xa8;
|
||||
|
@ -38,6 +40,12 @@ virtual-method Tile *setDestroyTime(float destroy_time) = 0xf8;
|
|||
|
||||
property int texture = 0x4;
|
||||
property int id = 0x8;
|
||||
property float x1 = 0xc;
|
||||
property float y1 = 0x10;
|
||||
property float z1 = 0x14;
|
||||
property float x2 = 0x18;
|
||||
property float y2 = 0x1c;
|
||||
property float z2 = 0x20;
|
||||
property int category = 0x3c;
|
||||
property AABB aabb = 0x40;
|
||||
|
||||
|
|
|
@ -2,7 +2,11 @@ size 0xb8;
|
|||
|
||||
constructor (Minecraft *minecraft, LevelSource *level) = 0x53e58;
|
||||
|
||||
static-method bool canRender(int shape) = 0x5accc;
|
||||
|
||||
method bool tesselateBlockInWorld(Tile *tile, int x, int y, int z) = 0x59e30;
|
||||
method bool tesselateInWorld(Tile *tile, int x, int y, int z) = 0x5e80c;
|
||||
method void renderGuiTile(Tile *tile, int aux) = 0x5ad0c;
|
||||
method void renderTile(Tile *tile, int data) = 0x5dcb0;
|
||||
|
||||
property LevelSource *level = 0x0;
|
||||
|
|
Loading…
Reference in New Issue
Block a user
IMO the history code should be part of chat, not the text input widget.
I agree, however that makes input trickier and setting the text harder (unless there was
isFocused
andsetText
methods). This also has the benefit of being really easy to add history to any other text input, such as for a modded terminal.Then, why not just... add
setText
andisFocused
methods? Realistically chat is the only thing that will ever need this code. And if something else does need it, it can also just be re-implemented really easily.Right, but what about input?
What do you mean? Just add code to
keyPressed
inchat/ui.cpp
.Done 👍