aboutsummaryrefslogtreecommitdiff
path: root/src/script/cpp_api/s_client.h
blob: 9133637a640fdf8d9514f0a45a9e6e99045293ee (plain)
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
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef S_CLIENT_H_
#define S_CLIENT_H_

#include "util/pointedthing.h"
#include "cpp_api/s_base.h"
#include "mapnode.h"
#include "itemdef.h"
#include "util/string.h"
#include "util/pointedthing.h"
#include "lua_api/l_item.h"

#ifdef _CRT_MSVCP_CURRENT
#include <cstdint>
#endif

class ClientEnvironment;

class ScriptApiClient : virtual public ScriptApiBase
{
public:
	// Calls on_shutdown handlers
	void on_shutdown();

	void on_connect();

	// Chat message handlers
	bool on_sending_message(const std::string &message);
	bool on_receiving_message(const std::string &message);

	void on_damage_taken(int32_t damage_amount);
	void on_hp_modification(int32_t newhp);
	void on_death();
	void environment_step(float dtime);
	void on_formspec_input(const std::string &formname, const StringMap &fields);

	bool on_dignode(v3s16 p, MapNode node);
	bool on_punchnode(v3s16 p, MapNode node);
	bool on_placenode(const PointedThing &pointed, const ItemDefinition &item);
	bool on_item_use(const ItemStack &item, const PointedThing &pointed);

	void setEnv(ClientEnvironment *env);
};
#endif
for fully transparent ones. // Note: loop y around x for better cache locality. for (u32 ctry = 0; ctry < dim.Height; ctry++) for (u32 ctrx = 0; ctrx < dim.Width; ctrx++) { // Ignore opaque pixels. irr::video::SColor c = src->getPixel(ctrx, ctry); if (c.getAlpha() > threshold) continue; // Sample size and total weighted r, g, b values. u32 ss = 0, sr = 0, sg = 0, sb = 0; // Walk each neighbor pixel (clipped to image bounds). for (u32 sy = (ctry < 1) ? 0 : (ctry - 1); sy <= (ctry + 1) && sy < dim.Height; sy++) for (u32 sx = (ctrx < 1) ? 0 : (ctrx - 1); sx <= (ctrx + 1) && sx < dim.Width; sx++) { // Ignore transparent pixels. irr::video::SColor d = src->getPixel(sx, sy); if (d.getAlpha() <= threshold) continue; // Add RGB values weighted by alpha. u32 a = d.getAlpha(); ss += a; sr += a * d.getRed(); sg += a * d.getGreen(); sb += a * d.getBlue(); } // If we found any neighbor RGB data, set pixel to average // weighted by alpha. if (ss > 0) { c.setRed(sr / ss); c.setGreen(sg / ss); c.setBlue(sb / ss); src->setPixel(ctrx, ctry, c); } } } /* Scale a region of an image into another image, using nearest-neighbor with * anti-aliasing; treat pixels as crisp rectangles, but blend them at boundaries * to prevent non-integer scaling ratio artifacts. Note that this may cause * some blending at the edges where pixels don't line up perfectly, but this * filter is designed to produce the most accurate results for both upscaling * and downscaling. */ void imageScaleNNAA(video::IImage *src, const core::rect<s32> &srcrect, video::IImage *dest) { double sx, sy, minsx, maxsx, minsy, maxsy, area, ra, ga, ba, aa, pw, ph, pa; u32 dy, dx; video::SColor pxl; // Cache rectsngle boundaries. double sox = srcrect.UpperLeftCorner.X * 1.0; double soy = srcrect.UpperLeftCorner.Y * 1.0; double sw = srcrect.getWidth() * 1.0; double sh = srcrect.getHeight() * 1.0; // Walk each destination image pixel. // Note: loop y around x for better cache locality. core::dimension2d<u32> dim = dest->getDimension(); for (dy = 0; dy < dim.Height; dy++) for (dx = 0; dx < dim.Width; dx++) { // Calculate floating-point source rectangle bounds. // Do some basic clipping, and for mirrored/flipped rects, // make sure min/max are in the right order. minsx = sox + (dx * sw / dim.Width); minsx = rangelim(minsx, 0, sw); maxsx = minsx + sw / dim.Width; maxsx = rangelim(maxsx, 0, sw); if (minsx > maxsx) SWAP(double, minsx, maxsx); minsy = soy + (dy * sh / dim.Height); minsy = rangelim(minsy, 0, sh); maxsy = minsy + sh / dim.Height; maxsy = rangelim(maxsy, 0, sh); if (minsy > maxsy) SWAP(double, minsy, maxsy); // Total area, and integral of r, g, b values over that area, // initialized to zero, to be summed up in next loops. area = 0; ra = 0; ga = 0; ba = 0; aa = 0; // Loop over the integral pixel positions described by those bounds. for (sy = floor(minsy); sy < maxsy; sy++) for (sx = floor(minsx); sx < maxsx; sx++) { // Calculate width, height, then area of dest pixel // that's covered by this source pixel. pw = 1; if (minsx > sx) pw += sx - minsx;