File: chat.cpp

package info (click to toggle)
btanks 0.9.8083-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 43,616 kB
  • sloc: cpp: 46,425; ansic: 12,005; xml: 4,262; python: 313; sh: 13; makefile: 13
file content (120 lines) | stat: -rw-r--r-- 2,616 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "chat.h"
#include "resource_manager.h"
#include "menu/text_control.h"
#include "sdlx/font.h"
#include "player_slot.h"
#include "team.h"

Chat::Chat() :nick_w(0), lines(10) {
	//GET_CONFIG_VALUE("multiplayer.chat.lines-number", int, lines, 6);
	_font[0] = ResourceManager->loadFont("small", true);
	for(int t = 0; t < 4; ++t)
		_font[t + 1] = ResourceManager->loadFont(mrt::format_string("small_%s", Team::get_color((Team::ID)t)), true);
	 
	add(4, 0, _input = new TextControl("small"));
}

void Chat::clear() {
	text.clear();
	nick_w = 0;
	_input->set(std::string());
	last_message.clear();
	hide();
	layout();
}

void Chat::render(sdlx::Surface &surface, const int x, const int y) const {
	int ybase = 0;
	for(Text::const_iterator i = text.begin(); i != text.end(); ++i) {
		const Line &line = *i;
		if (!line.nick.empty()) {
			line.font->render(surface, x + 4, y + ybase, line.nick);
			line.font->render(surface, x + 4 + nick_w, y + ybase, line.message);
		} else {
			line.font->render(surface, x + 4, y + ybase, line.message);
		}
		ybase += line.font->get_height();
	}
	if (!hidden())
		Container::render(surface, x, y);
}

void Chat::layout() {
	int xp = 4;
	int yp = 0;
	nick_w = 0;
	for(Text::const_iterator i = text.begin(); i != text.end(); ++i) {
		const Line &line = *i;
		if (!line.nick.empty()) { 
			int w = line.font->render(NULL, 0, 0, line.nick);
			if (w > nick_w)
				nick_w = w;
		}
		yp += line.font->get_height();
	}
	_input->set_base(xp, yp);
}

void Chat::addAction(const std::string &m) {
	Line line(std::string(), "*" + m, _font[0]);
	text.push_back(line);
	
	if (text.size() > lines)
		text.erase(text.begin());
	
	layout();
}



void Chat::add_message(const PlayerSlot &slot, const std::string &m) {
	const std::string n = "<" + slot.name + ">";
	int idx = (int)slot.team + 1;
	assert(idx >= 0 && idx < 5);

	Line line(n, m, _font[idx]);
	text.push_back(line);
	
	if (text.size() > lines)
		text.erase(text.begin());
	
	layout();
}


bool Chat::onKey(const SDL_keysym sym) {
	switch(sym.sym) {
	case SDLK_KP_ENTER:
	case SDLK_RETURN: 
		last_message = _input->get();
					
	case SDLK_ESCAPE: 
		if (sym.sym == SDLK_ESCAPE) 
			last_message.clear();
		
		_input->set(std::string());
		invalidate(true);
		return true;
	default: 
		Container::onKey(sym);
	}
	return true;
}

void Chat::tick(const float dt) {
	Container::tick(dt);

	bool do_layout = false;
	float max = 10;
	for(std::deque<Line>::iterator i = text.begin(); i != text.end();) {
		i->t += dt;
		if (i->t >= max) {
			i = text.erase(i);
			do_layout = true;
		} else {
			++i;
		}
	}
	if (do_layout)
		layout();
}