aboutsummaryrefslogtreecommitdiff
path: root/src/scriptapi.h
blob: f63cab3681c45971fcf5e6a9d93d29b17c517de1 (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
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
/*
Minetest-c55
Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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 General Public License for more details.

You should have received a copy of the GNU 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 SCRIPTAPI_HEADER
#define SCRIPTAPI_HEADER

#include "irrlichttypes.h"
#include <string>
#include "mapnode.h"

class Server;
class ServerEnvironment;
class ServerActiveObject;
class ServerRemotePlayer;
typedef struct lua_State lua_State;
struct LuaEntityProperties;
struct ItemStack;
struct PointedThing;
//class IGameDef;
struct ToolCapabilities;

void scriptapi_export(lua_State *L, Server *server);
bool scriptapi_loadmod(lua_State *L, const std::string &scriptpath,
		const std::string &modname);
void scriptapi_add_environment(lua_State *L, ServerEnvironment *env);

void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj);
void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj);

// Returns true if script handled message
bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
		const std::string &message);

/* environment */
// On environment step
void scriptapi_environment_step(lua_State *L, float dtime);
// After generating a piece of map
void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp);

/* misc */
void scriptapi_on_newplayer(lua_State *L, ServerActiveObject *player);
void scriptapi_on_dieplayer(lua_State *L, ServerActiveObject *player);
bool scriptapi_on_respawnplayer(lua_State *L, ServerActiveObject *player);
void scriptapi_get_creative_inventory(lua_State *L, ServerRemotePlayer *player);

/* item callbacks */
bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
		ServerActiveObject *dropper, v3f pos);
bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
		ServerActiveObject *placer, const PointedThing &pointed);
bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
		ServerActiveObject *user, const PointedThing &pointed);

/* node callbacks */
bool scriptapi_node_on_punch(lua_State *L, v3s16 p, MapNode node,
		ServerActiveObject *puncher);
bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node,
		ServerActiveObject *digger);

/* luaentity */
// Returns true if succesfully added into Lua; false otherwise.
bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name);
void scriptapi_luaentity_activate(lua_State *L, u16 id,
		const std::string &staticdata);
void scriptapi_luaentity_rm(lua_State *L, u16 id);
std::string scriptapi_luaentity_get_staticdata(lua_State *L, u16 id);
void scriptapi_luaentity_get_properties(lua_State *L, u16 id,
		LuaEntityProperties *prop);
void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime);
void scriptapi_luaentity_punch(lua_State *L, u16 id,
		ServerActiveObject *puncher, float time_from_last_punch,
		const ToolCapabilities *toolcap, v3f dir);
void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
		ServerActiveObject *clicker);

#endif

pan class="hl opt">; static void cloud_3d_setting_changed(const std::string &settingname, void *data) { ((Clouds *)data)->readSettings(); } Clouds::Clouds( scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, u32 seed, s16 cloudheight ): scene::ISceneNode(parent, mgr, id), m_seed(seed), m_camera_pos(0,0), m_time(0), m_camera_offset(0,0,0) { m_material.setFlag(video::EMF_LIGHTING, false); //m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BACK_FACE_CULLING, true); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, true); m_material.setFlag(video::EMF_ANTI_ALIASING, true); //m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m_passed_cloud_y = cloudheight; readSettings(); g_settings->registerChangedCallback("enable_3d_clouds", &cloud_3d_setting_changed, this); m_box = core::aabbox3d<f32>(-BS*1000000,m_cloud_y-BS,-BS*1000000, BS*1000000,m_cloud_y+BS,BS*1000000); } Clouds::~Clouds() { g_settings->deregisterChangedCallback("enable_3d_clouds", &cloud_3d_setting_changed, this); } void Clouds::OnRegisterSceneNode() { if(IsVisible) { SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT); //SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID); } ISceneNode::OnRegisterSceneNode(); } #define MYROUND(x) (x > 0.0 ? (int)x : (int)x - 1) void Clouds::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) //if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) return; ScopeProfiler sp(g_profiler, "Rendering of clouds, avg", SPT_AVG); int num_faces_to_draw = m_enable_3d ? 6 : 1; m_material.setFlag(video::EMF_BACK_FACE_CULLING, m_enable_3d); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setMaterial(m_material); /* Clouds move from Z+ towards Z- */ const float cloud_size = BS * 64; const v2f cloud_speed(0, -BS * 2); const float cloud_full_radius = cloud_size * m_cloud_radius_i; // Position of cloud noise origin in world coordinates v2f world_cloud_origin_pos_f = m_time * cloud_speed; // Position of cloud noise origin from the camera v2f cloud_origin_from_camera_f = world_cloud_origin_pos_f - m_camera_pos; // The center point of drawing in the noise v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f; // The integer center point of drawing in the noise v2s16 center_of_drawing_in_noise_i( MYROUND(center_of_drawing_in_noise_f.X / cloud_size), MYROUND(center_of_drawing_in_noise_f.Y / cloud_size) ); // The world position of the integer center point of drawing in the noise v2f world_center_of_drawing_in_noise_f = v2f( center_of_drawing_in_noise_i.X * cloud_size, center_of_drawing_in_noise_i.Y * cloud_size ) + world_cloud_origin_pos_f; /*video::SColor c_top(128,b*240,b*240,b*255); video::SColor c_side_1(128,b*230,b*230,b*255); video::SColor c_side_2(128,b*220,b*220,b*245); video::SColor c_bottom(128,b*205,b*205,b*230);*/ video::SColorf c_top_f(m_color); video::SColorf c_side_1_f(m_color); video::SColorf c_side_2_f(m_color); video::SColorf c_bottom_f(m_color); c_side_1_f.r *= 0.95; c_side_1_f.g *= 0.95; c_side_1_f.b *= 0.95; c_side_2_f.r *= 0.90; c_side_2_f.g *= 0.90; c_side_2_f.b *= 0.90; c_bottom_f.r *= 0.80; c_bottom_f.g *= 0.80; c_bottom_f.b *= 0.80; c_top_f.a = 0.9; c_side_1_f.a = 0.9; c_side_2_f.a = 0.9; c_bottom_f.a = 0.9; video::SColor c_top = c_top_f.toSColor(); video::SColor c_side_1 = c_side_1_f.toSColor(); video::SColor c_side_2 = c_side_2_f.toSColor(); video::SColor c_bottom = c_bottom_f.toSColor(); // Get fog parameters for setting them back later video::SColor fog_color(0,0,0,0); video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR; f32 fog_start = 0; f32 fog_end = 0; f32 fog_density = 0; bool fog_pixelfog = false; bool fog_rangefog = false; driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density, fog_pixelfog, fog_rangefog); // Set our own fog driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5, cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog); // Read noise bool *grid = new bool[m_cloud_radius_i * 2 * m_cloud_radius_i * 2]; float cloud_size_noise = cloud_size / BS / 200; for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) { u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i; for (s16 xi = -m_cloud_radius_i; xi < m_cloud_radius_i; xi++) { u32 i = si + xi; v2s16 p_in_noise_i( xi + center_of_drawing_in_noise_i.X, zi + center_of_drawing_in_noise_i.Y ); double noise = noise2d_perlin( (float)p_in_noise_i.X * cloud_size_noise, (float)p_in_noise_i.Y * cloud_size_noise, m_seed, 3, 0.5); grid[i] = (noise >= 0.4); } } #define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius)) #define INAREA(x, z, radius) \ ((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius)) for (s16 zi0= -m_cloud_radius_i; zi0 < m_cloud_radius_i; zi0++) for (s16 xi0= -m_cloud_radius_i; xi0 < m_cloud_radius_i; xi0++) { s16 zi = zi0; s16 xi = xi0; // Draw from front to back (needed for transparency) /*if(zi <= 0) zi = -m_cloud_radius_i - zi; if(xi <= 0) xi = -m_cloud_radius_i - xi;*/ // Draw from back to front if(zi >= 0) zi = m_cloud_radius_i - zi - 1; if(xi >= 0) xi = m_cloud_radius_i - xi - 1; u32 i = GETINDEX(xi, zi, m_cloud_radius_i); if(grid[i] == false) continue; v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f; video::S3DVertex v[4] = { video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1), video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1), video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0), video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0) }; /*if(zi <= 0 && xi <= 0){ v[0].Color.setBlue(255); v[1].Color.setBlue(255); v[2].Color.setBlue(255); v[3].Color.setBlue(255); }*/ f32 rx = cloud_size/2; f32 ry = 8 * BS; f32 rz = cloud_size / 2; for(int i=0; i<num_faces_to_draw; i++) { switch(i) { case 0: // top for(int j=0;j<4;j++){ v[j].Normal.set(0,1,0); } v[0].Pos.set(-rx, ry,-rz); v[1].Pos.set(-rx, ry, rz); v[2].Pos.set( rx, ry, rz); v[3].Pos.set( rx, ry,-rz); break; case 1: // back if (INAREA(xi, zi - 1, m_cloud_radius_i)) { u32 j = GETINDEX(xi, zi - 1, m_cloud_radius_i); if(grid[j]) continue; } for(int j=0;j<4;j++){ v[j].Color = c_side_1; v[j].Normal.set(0,0,-1); } v[0].Pos.set(-rx, ry,-rz);