virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		int cold = ((ItemGroupList) ndef->get(neighbor).groups)["cold"];
		int freeze = ((ItemGroupList) ndef->get(n).groups)["freeze"];
		if (cold < freeze) {
			n.freeze_melt(ndef, -1);
			map->setNode(p, n);
		}
	}
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		int hot = ((ItemGroupList) ndef->get(neighbor).groups)["hot"];
		int melt = ((ItemGroupList) ndef->get(n).groups)["melt"];
		if (hot > melt) {
			n.freeze_melt(ndef, +1);
			map->setNode(p, n);
			env->nodeUpdate(p, 2);
		}
	}
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();

		float heat = map->updateBlockHeat(env, p);
		//heater = rare
		content_t c = map->getNodeTry(p - v3POS(0,  -1, 0 )).getContent(); // top
		//more chance to freeze if air at top
		static int water_level = g_settings->getS16("water_level");
		bool top_liquid = ndef->get(n).liquid_type > LIQUID_NONE && p.Y > water_level;
		int freeze = ((ItemGroupList) ndef->get(n).groups)["freeze"];
		if (heat <= freeze - 1 && ((!top_liquid && (activate || (heat <= freeze - 50))) || heat <= freeze - 50 ||
		                           (myrand_range(freeze - 50, heat) <= (freeze + (top_liquid ? -42 : c == CONTENT_AIR ? -10 : -40))))) {
			content_t c_self = n.getContent();
			// making freeze not annoying, do not freeze random blocks in center of ocean
			// todo: any block not water (dont freeze _source near _flowing)
			bool allow = activate || heat < freeze - 40;
			// todo: make for(...)
			if (!allow) {
				c = map->getNodeTry(p - v3POS(0,  1, 0 )).getContent(); // below
				if (c == CONTENT_AIR || c == CONTENT_IGNORE)
					if (ndef->get(n.getContent()).liquid_type == LIQUID_FLOWING || ndef->get(n.getContent()).liquid_type == LIQUID_SOURCE)
						return; // do not freeze when falling
				if (c != c_self && c != CONTENT_IGNORE) allow = 1;
				if (!allow) {
					c = map->getNodeTry(p - v3POS(1,  0, 0 )).getContent(); // right
					if (c != c_self && c != CONTENT_IGNORE) allow = 1;
					if (!allow) {
						c = map->getNodeTry(p - v3POS(-1, 0, 0 )).getContent(); // left
						if (c != c_self && c != CONTENT_IGNORE) allow = 1;
						if (!allow) {
							c = map->getNodeTry(p - v3POS(0,  0, 1 )).getContent(); // back
							if (c != c_self && c != CONTENT_IGNORE) allow = 1;
							if (!allow) {
								c = map->getNodeTry(p - v3POS(0,  0, -1)).getContent(); // front
								if (c != c_self && c != CONTENT_IGNORE) allow = 1;
							}
						}
					}
				}
			}
			if (allow) {
				n.freeze_melt(ndef, -1);
				map->setNode(p, n);
			}
		}
	}
Exemple #4
0
// freeze_melt(pos, direction)
// pos = {x=num, y=num, z=num}
// direction: -1 (freeze), 1 (melt)
int ModApiEnvMod::l_freeze_melt(lua_State *L)
{
	GET_ENV_PTR;

	v3s16 pos = read_v3s16(L, 1);
	int direction = 1;
	if(lua_isnumber(L, 2))
		direction = lua_tonumber(L, 2);
	MapNode n = env->getMap().getNodeNoEx(pos);
	if(n.getContent() == CONTENT_IGNORE){
		lua_pushnumber(L, 0);
		return 1;
	}
	lua_pushnumber(L, n.freeze_melt(env->getGameDef()->ndef(), direction));
	env->setNode(pos, n);
	return 1;
}
	virtual void trigger(ServerEnvironment *env, v3POS p, MapNode n,
	                     u32 active_object_count, u32 active_object_count_wider, MapNode neighbor, bool activate) {
		ServerMap *map = &env->getServerMap();
		INodeDefManager *ndef = env->getGameDef()->ndef();
		float heat = map->updateBlockHeat(env, p);
		content_t c = map->getNodeTry(p - v3POS(0,  -1, 0 )).getContent(); // top
		int melt = ((ItemGroupList) ndef->get(n).groups)["melt"];
		if (heat >= melt + 1 && (activate || heat >= melt + 40 ||
		                         ((myrand_range(heat, melt + 40)) >= (c == CONTENT_AIR ? melt + 10 : melt + 20)))) {
			if (ndef->get(n.getContent()).liquid_type == LIQUID_FLOWING || ndef->get(n.getContent()).liquid_type == LIQUID_SOURCE) {
				c = map->getNodeTry(p - v3POS(0,  1, 0 )).getContent(); // below
				if (c == CONTENT_AIR || c == CONTENT_IGNORE)
					return; // do not melt when falling (dirt->dirt_with_grass on air)
			}
			n.freeze_melt(ndef, +1);
			map->setNode(p, n);
			env->nodeUpdate(p, 2); //enable after making FAST nodeupdate
		}
	}