Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
I
illuna-minetest
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Illuna-Minetest
illuna-minetest
Commits
976ec31c
Commit
976ec31c
authored
13 years ago
by
Perttu Ahola
Browse files
Options
Downloads
Patches
Plain Diff
switched to old transformLiquids, new one is not ready
parent
98be7787
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/map.cpp
+216
-207
216 additions, 207 deletions
src/map.cpp
with
216 additions
and
207 deletions
src/map.cpp
+
216
−
207
View file @
976ec31c
...
@@ -1540,17 +1540,6 @@ void Map::PrintInfo(std::ostream &out)
...
@@ -1540,17 +1540,6 @@ void Map::PrintInfo(std::ostream &out)
#define WATER_DROP_BOOST 4
#define WATER_DROP_BOOST 4
enum
NeighborType
{
NEIGHBOR_UPPER
,
NEIGHBOR_SAME_LEVEL
,
NEIGHBOR_LOWER
};
struct
NodeNeighbor
{
MapNode
n
;
NeighborType
t
;
v3s16
p
;
};
void
Map
::
transformLiquids
(
core
::
map
<
v3s16
,
MapBlock
*>
&
modified_blocks
)
void
Map
::
transformLiquids
(
core
::
map
<
v3s16
,
MapBlock
*>
&
modified_blocks
)
{
{
DSTACK
(
__FUNCTION_NAME
);
DSTACK
(
__FUNCTION_NAME
);
...
@@ -1570,220 +1559,240 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
...
@@ -1570,220 +1559,240 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
v3s16
p0
=
m_transforming_liquid
.
pop_front
();
v3s16
p0
=
m_transforming_liquid
.
pop_front
();
MapNode
n0
=
getNodeNoEx
(
p0
);
MapNode
n0
=
getNodeNoEx
(
p0
);
/*
// Don't deal with non-liquids
Collect information about current node
if
(
content_liquid
(
n0
.
d
)
==
false
)
*/
continue
;
s8
liquid_level
=
-
1
;
u8
liquid_kind
=
CONTENT_IGNORE
;
bool
is_source
=
!
content_flowing_liquid
(
n0
.
d
);
LiquidType
liquid_type
=
content_features
(
n0
.
d
).
liquid_type
;
switch
(
liquid_type
)
{
u8
liquid_level
=
8
;
case
LIQUID_SOURCE
:
if
(
is_source
==
false
)
liquid_level
=
8
;
liquid_level
=
n0
.
param2
&
0x0f
;
liquid_kind
=
content_features
(
n0
.
d
).
liquid_alternative_flowing
;
break
;
// Turn possible source into non-source
case
LIQUID_FLOWING
:
u8
nonsource_c
=
make_liquid_flowing
(
n0
.
d
);
liquid_level
=
(
n0
.
param2
&
LIQUID_LEVEL_MASK
);
liquid_kind
=
n0
.
d
;
break
;
case
LIQUID_NONE
:
// if this is an air node, it *could* be transformed into a liquid. otherwise,
// continue with the next node.
if
(
n0
.
d
!=
CONTENT_AIR
)
continue
;
liquid_kind
=
CONTENT_AIR
;
break
;
}
/*
/*
Collect information about the environment
If not source, check that some node flows into this one
*/
and what is the level of liquid in this one
v3s16
dirs
[
6
]
=
{
*/
v3s16
(
0
,
1
,
0
),
// top
if
(
is_source
==
false
)
v3s16
(
0
,
-
1
,
0
),
// bottom
{
v3s16
(
1
,
0
,
0
),
// right
s8
new_liquid_level_max
=
-
1
;
v3s16
(
-
1
,
0
,
0
),
// left
v3s16
(
0
,
0
,
1
),
// back
v3s16
dirs_from
[
5
]
=
{
v3s16
(
0
,
0
,
-
1
),
// front
v3s16
(
0
,
1
,
0
),
// top
};
v3s16
(
0
,
0
,
1
),
// back
NodeNeighbor
sources
[
6
];
// surrounding sources
v3s16
(
1
,
0
,
0
),
// right
int
num_sources
=
0
;
v3s16
(
0
,
0
,
-
1
),
// front
NodeNeighbor
flows
[
6
];
// surrounding flowing liquid nodes
v3s16
(
-
1
,
0
,
0
),
// left
int
num_flows
=
0
;
};
NodeNeighbor
airs
[
6
];
// surrounding air
for
(
u16
i
=
0
;
i
<
5
;
i
++
)
int
num_airs
=
0
;
{
NodeNeighbor
neutrals
[
6
];
// nodes that are solid or another kind of liquid
bool
from_top
=
(
i
==
0
);
int
num_neutrals
=
0
;
bool
flowing_down
=
false
;
v3s16
p2
=
p0
+
dirs_from
[
i
];
for
(
u16
i
=
0
;
i
<
6
;
i
++
)
{
MapNode
n2
=
getNodeNoEx
(
p2
);
NeighborType
nt
=
NEIGHBOR_SAME_LEVEL
;
switch
(
i
)
{
if
(
content_liquid
(
n2
.
d
))
case
0
:
{
nt
=
NEIGHBOR_UPPER
;
u8
n2_nonsource_c
=
make_liquid_flowing
(
n2
.
d
);
break
;
// Check that the liquids are the same type
case
1
:
if
(
n2_nonsource_c
!=
nonsource_c
)
nt
=
NEIGHBOR_LOWER
;
{
break
;
dstream
<<
"WARNING: Not handling: different liquids"
}
" collide"
<<
std
::
endl
;
v3s16
npos
=
p0
+
dirs
[
i
];
continue
;
NodeNeighbor
nb
=
{
getNodeNoEx
(
npos
),
nt
,
npos
};
switch
(
content_features
(
nb
.
n
.
d
).
liquid_type
)
{
case
LIQUID_NONE
:
if
(
nb
.
n
.
d
==
CONTENT_AIR
)
{
airs
[
num_airs
++
]
=
nb
;
// if the current node happens to be a flowing node, it will start to flow down here.
if
(
nb
.
t
==
NEIGHBOR_LOWER
)
flowing_down
=
true
;
}
else
{
neutrals
[
num_neutrals
++
]
=
nb
;
}
}
break
;
bool
n2_is_source
=
!
content_flowing_liquid
(
n2
.
d
);
case
LIQUID_SOURCE
:
s8
n2_liquid_level
=
8
;
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
if
(
n2_is_source
==
false
)
if
(
liquid_kind
==
CONTENT_AIR
)
n2_liquid_level
=
n2
.
param2
&
0x07
;
liquid_kind
=
content_features
(
nb
.
n
.
d
).
liquid_alternative_flowing
;
if
(
content_features
(
nb
.
n
.
d
).
liquid_alternative_flowing
!=
liquid_kind
)
{
s8
new_liquid_level
=
-
1
;
neutrals
[
num_neutrals
++
]
=
nb
;
if
(
from_top
)
}
else
{
{
sources
[
num_sources
++
]
=
nb
;
//new_liquid_level = 7;
if
(
n2_liquid_level
>=
7
-
WATER_DROP_BOOST
)
new_liquid_level
=
7
;
else
new_liquid_level
=
n2_liquid_level
+
WATER_DROP_BOOST
;
}
}
break
;
else
if
(
n2_liquid_level
>
0
)
case
LIQUID_FLOWING
:
{
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
new_liquid_level
=
n2_liquid_level
-
1
;
if
(
liquid_kind
==
CONTENT_AIR
)
liquid_kind
=
content_features
(
nb
.
n
.
d
).
liquid_alternative_flowing
;
if
(
content_features
(
nb
.
n
.
d
).
liquid_alternative_flowing
!=
liquid_kind
)
{
neutrals
[
num_neutrals
++
]
=
nb
;
}
else
{
flows
[
num_flows
++
]
=
nb
;
if
(
nb
.
t
==
NEIGHBOR_LOWER
)
flowing_down
=
true
;
}
}
break
;
}
if
(
new_liquid_level
>
new_liquid_level_max
)
}
new_liquid_level_max
=
new_liquid_level
;
/*
decide on the type (and possibly level) of the current node
*/
u8
new_node_content
;
s8
new_node_level
=
-
1
;
if
(
num_sources
>=
2
||
liquid_type
==
LIQUID_SOURCE
)
{
// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
// or the flowing alternative of the first of the surrounding sources (if it's air), so
// it's perfectly safe to use liquid_kind here to determine the new node content.
new_node_content
=
content_features
(
liquid_kind
).
liquid_alternative_source
;
}
else
if
(
num_sources
==
1
&&
sources
[
0
].
t
!=
NEIGHBOR_LOWER
)
{
// liquid_kind is set properly, see above
new_node_content
=
liquid_kind
;
new_node_level
=
7
;
}
else
{
// no surrounding sources, so get the maximum level that can flow into this node
for
(
u16
i
=
0
;
i
<
num_flows
;
i
++
)
{
u8
nb_liquid_level
=
(
flows
[
i
].
n
.
param2
&
LIQUID_LEVEL_MASK
);
switch
(
flows
[
i
].
t
)
{
case
NEIGHBOR_UPPER
:
if
(
nb_liquid_level
+
WATER_DROP_BOOST
>
new_node_level
)
{
new_node_level
=
7
;
if
(
nb_liquid_level
+
WATER_DROP_BOOST
<
7
)
new_node_level
=
nb_liquid_level
+
WATER_DROP_BOOST
;
}
break
;
case
NEIGHBOR_LOWER
:
break
;
case
NEIGHBOR_SAME_LEVEL
:
if
((
flows
[
i
].
n
.
param2
&
LIQUID_FLOW_DOWN_MASK
)
!=
LIQUID_FLOW_DOWN_MASK
&&
nb_liquid_level
>
0
&&
nb_liquid_level
-
1
>
new_node_level
)
{
new_node_level
=
nb_liquid_level
-
1
;
}
break
;
}
}
}
}
//for
// don't flow as far in open terrain - if there isn't at least one adjacent solid block,
// substract another unit from the resulting water level.
/*
if
(
!
flowing_down
&&
new_node_level
>=
1
)
{
If liquid level should be something else, update it and
bool
at_wall
=
false
;
add all the neighboring water nodes to the transform queue.
for
(
u16
i
=
0
;
i
<
num_neutrals
;
i
++
)
{
*/
if
(
neutrals
[
i
].
t
==
NEIGHBOR_SAME_LEVEL
)
{
if
(
new_liquid_level_max
!=
liquid_level
)
at_wall
=
true
;
{
break
;
if
(
new_liquid_level_max
==
-
1
)
{
// Remove water alltoghether
n0
.
d
=
CONTENT_AIR
;
n0
.
param2
=
0
;
setNode
(
p0
,
n0
);
}
else
{
n0
.
param2
=
new_liquid_level_max
;
setNode
(
p0
,
n0
);
}
// Block has been modified
{
v3s16
blockpos
=
getNodeBlockPos
(
p0
);
MapBlock
*
block
=
getBlockNoCreateNoEx
(
blockpos
);
if
(
block
!=
NULL
)
modified_blocks
.
insert
(
blockpos
,
block
);
}
/*
Add neighboring non-source liquid nodes to transform queue.
*/
v3s16
dirs
[
6
]
=
{
v3s16
(
0
,
0
,
1
),
// back
v3s16
(
0
,
1
,
0
),
// top
v3s16
(
1
,
0
,
0
),
// right
v3s16
(
0
,
0
,
-
1
),
// front
v3s16
(
0
,
-
1
,
0
),
// bottom
v3s16
(
-
1
,
0
,
0
),
// left
};
for
(
u16
i
=
0
;
i
<
6
;
i
++
)
{
v3s16
p2
=
p0
+
dirs
[
i
];
MapNode
n2
=
getNodeNoEx
(
p2
);
if
(
content_flowing_liquid
(
n2
.
d
))
{
m_transforming_liquid
.
push_back
(
p2
);
}
}
}
}
if
(
!
at_wall
)
new_node_level
-=
1
;
}
}
if
(
new_node_level
>=
0
)
new_node_content
=
liquid_kind
;
else
new_node_content
=
CONTENT_AIR
;
}
}
/*
// Get a new one from queue if the node has turned into non-water
check if anything has changed. if not, just continue with the next node.
if
(
content_liquid
(
n0
.
d
)
==
false
)
*/
if
(
new_node_content
==
n0
.
d
&&
(
content_features
(
n0
.
d
).
liquid_type
!=
LIQUID_FLOWING
||
((
n0
.
param2
&
LIQUID_LEVEL_MASK
)
==
(
u8
)
new_node_level
&&
((
n0
.
param2
&
LIQUID_FLOW_DOWN_MASK
)
==
LIQUID_FLOW_DOWN_MASK
)
==
flowing_down
)))
continue
;
continue
;
/*
update the current node
*/
bool
flow_down_enabled
=
(
flowing_down
&&
((
n0
.
param2
&
LIQUID_FLOW_DOWN_MASK
)
!=
LIQUID_FLOW_DOWN_MASK
));
n0
.
d
=
new_node_content
;
if
(
content_features
(
n0
.
d
).
liquid_type
==
LIQUID_FLOWING
)
{
// set level to last 3 bits, flowing down bit to 4th bit
n0
.
param2
=
(
flowing_down
?
LIQUID_FLOW_DOWN_MASK
:
0x00
)
|
(
new_node_level
&
LIQUID_LEVEL_MASK
);
}
else
{
n0
.
param2
=
0
;
}
setNode
(
p0
,
n0
);
v3s16
blockpos
=
getNodeBlockPos
(
p0
);
MapBlock
*
block
=
getBlockNoCreateNoEx
(
blockpos
);
if
(
block
!=
NULL
)
modified_blocks
.
insert
(
blockpos
,
block
);
/*
/*
enqueue neighbors for update if neccessary
Flow water from this node
*/
*/
switch
(
content_features
(
n0
.
d
).
liquid_type
)
{
v3s16
dirs_to
[
5
]
=
{
case
LIQUID_SOURCE
:
v3s16
(
0
,
-
1
,
0
),
// bottom
// make sure source flows into all neighboring nodes
v3s16
(
0
,
0
,
1
),
// back
for
(
u16
i
=
0
;
i
<
num_flows
;
i
++
)
v3s16
(
1
,
0
,
0
),
// right
if
(
flows
[
i
].
t
!=
NEIGHBOR_UPPER
)
v3s16
(
0
,
0
,
-
1
),
// front
m_transforming_liquid
.
push_back
(
flows
[
i
].
p
);
v3s16
(
-
1
,
0
,
0
),
// left
for
(
u16
i
=
0
;
i
<
num_airs
;
i
++
)
};
if
(
airs
[
i
].
t
!=
NEIGHBOR_UPPER
)
for
(
u16
i
=
0
;
i
<
5
;
i
++
)
m_transforming_liquid
.
push_back
(
airs
[
i
].
p
);
{
break
;
bool
to_bottom
=
(
i
==
0
);
case
LIQUID_NONE
:
// this flow has turned to air; neighboring flows might need to do the same
// If liquid is at lowest possible height, it's not going
for
(
u16
i
=
0
;
i
<
num_flows
;
i
++
)
// anywhere except down
m_transforming_liquid
.
push_back
(
flows
[
i
].
p
);
if
(
liquid_level
==
0
&&
to_bottom
==
false
)
break
;
continue
;
case
LIQUID_FLOWING
:
for
(
u16
i
=
0
;
i
<
num_flows
;
i
++
)
{
u8
liquid_next_level
=
0
;
u8
flow_level
=
(
flows
[
i
].
n
.
param2
&
LIQUID_LEVEL_MASK
);
// If going to bottom
// liquid_level is still the ORIGINAL level of this node.
if
(
to_bottom
)
if
(
flows
[
i
].
t
!=
NEIGHBOR_UPPER
&&
((
flow_level
<
liquid_level
||
flow_level
<
new_node_level
)
||
{
flow_down_enabled
))
//liquid_next_level = 7;
m_transforming_liquid
.
push_back
(
flows
[
i
].
p
);
if
(
liquid_level
>=
7
-
WATER_DROP_BOOST
)
liquid_next_level
=
7
;
else
liquid_next_level
=
liquid_level
+
WATER_DROP_BOOST
;
}
else
liquid_next_level
=
liquid_level
-
1
;
bool
n2_changed
=
false
;
bool
flowed
=
false
;
v3s16
p2
=
p0
+
dirs_to
[
i
];
MapNode
n2
=
getNodeNoEx
(
p2
);
//dstream<<"[1] n2.param="<<(int)n2.param<<std::endl;
if
(
content_liquid
(
n2
.
d
))
{
u8
n2_nonsource_c
=
make_liquid_flowing
(
n2
.
d
);
// Check that the liquids are the same type
if
(
n2_nonsource_c
!=
nonsource_c
)
{
dstream
<<
"WARNING: Not handling: different liquids"
" collide"
<<
std
::
endl
;
continue
;
}
bool
n2_is_source
=
!
content_flowing_liquid
(
n2
.
d
);
u8
n2_liquid_level
=
8
;
if
(
n2_is_source
==
false
)
n2_liquid_level
=
n2
.
param2
&
0x07
;
if
(
to_bottom
)
{
flowed
=
true
;
}
}
for
(
u16
i
=
0
;
i
<
num_airs
;
i
++
)
{
if
(
airs
[
i
].
t
!=
NEIGHBOR_UPPER
&&
(
airs
[
i
].
t
==
NEIGHBOR_LOWER
||
new_node_level
>
0
))
if
(
n2_is_source
)
m_transforming_liquid
.
push_back
(
airs
[
i
].
p
);
{
// Just flow into the source, nothing changes.
// n2_changed is not set because destination didn't change
flowed
=
true
;
}
else
{
if
(
liquid_next_level
>
liquid_level
)
{
n2
.
param2
=
liquid_next_level
;
setNode
(
p2
,
n2
);
n2_changed
=
true
;
flowed
=
true
;
}
}
}
}
else
if
(
n2
.
d
==
CONTENT_AIR
)
{
n2
.
d
=
nonsource_c
;
n2
.
param2
=
liquid_next_level
;
setNode
(
p2
,
n2
);
n2_changed
=
true
;
flowed
=
true
;
}
//dstream<<"[2] n2.param="<<(int)n2.param<<std::endl;
if
(
n2_changed
)
{
m_transforming_liquid
.
push_back
(
p2
);
v3s16
blockpos
=
getNodeBlockPos
(
p2
);
MapBlock
*
block
=
getBlockNoCreateNoEx
(
blockpos
);
if
(
block
!=
NULL
)
modified_blocks
.
insert
(
blockpos
,
block
);
}
// If n2_changed to bottom, don't flow anywhere else
if
(
to_bottom
&&
flowed
&&
!
is_source
)
break
;
break
;
}
}
loopcount
++
;
loopcount
++
;
//if(loopcount >= 100000)
//if(loopcount >= 100000)
if
(
loopcount
>=
initial_size
*
1
0
)
{
if
(
loopcount
>=
initial_size
*
1
)
break
;
break
;
}
}
}
//dstream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
//dstream<<"Map::transformLiquids(): loopcount="<<loopcount<<std::endl;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment