/*bltype 7 root 8 trunk 9 treetop 10 branch 11 branchEndingLeft 12 branchEndingRight 13 branchEndingLeftStop 14 branchEndingRightStop 15 treeLeaves 16 treeLeavesEnding 17 arcon int defaultStoneBlockWeight=11; int defaultWoodBlockWeight=5; int defaultWoodBondStrength=100; const int maxTreeHeight=13; const int minTreeBranchSpacing=1; const int treeBranchGrowthChance=12; const int minTreeBranchSpacingFromGround=1; const int minTreeBranchLenght=0; const int maxTreeBranchLenght=4; const int treeBranchEndingChance=4; const int maxTreeLeavesThick=4; const int treeLeafGrowthChance=7; const int treeLeafEndingChance=4; const int arconGrowthChance=25; */ #define jindex x+y*width int bltype[width*height]; int weight[height*width]; int bond_ver[height*width]; int bond_hor[height*width]; int architecture[height*width]; class architecture_bit_t { public: static const int stationary=1; static const int dynamic=2; static const int bond_down=4; static const int bond_right=8; static const int temporary_unstable=16; }; architecture_bit_t architecture_bit; //================================================= // process trees for(int y=0;y1){ // there is Trunk and old top below bltype[x+(y-he+1)*width]=8; //turn old top to trunk } //place treeTop bltype[x+(y-he)*width]=9; architecture[x+(y-he)*width]=architecture_bit.dynamic | architecture_bit.bond_down; bond_ver[x+(y-he)*width]=defaultWoodBondStrength; weight[x+(y-he)*width]=defaultStoneBlockWeight; heightReached++; break; }else{ if((bltype[x+(y-he)*width]==8)||(bltype[x+(y-he)*width]==9)&& ( (architecture[x+(y-he)*width] & architecture_bit.bond_down)!=0 ) ){ // this is still tree heightReached++; continue; }else{ // this is not tree any more break; } } } int newBranchThisMove=0; if(heightReached> minTreeBranchSpacingFromGround){ int sideBranchFreeSpaceCounter=0; int zoneStartIndex=y-minTreeBranchSpacingFromGround-1; int zoneStopIndex=zoneStartIndex; if(x+10){ zoneStopIndex--; } if(sideBranchFreeSpaceCounter==0){ zoneStartIndex=y-trunkIndex; zoneStopIndex=zoneStartIndex; } sideBranchFreeSpaceCounter++; }else{ sideBranchFreeSpaceCounter=0-minTreeBranchSpacing; } } if(sideBranchFreeSpaceCounter>0){ // branch-free space, can try to create branch for(int branchTryIndex=zoneStartIndex;branchTryIndex>zoneStopIndex;branchTryIndex--) if((rand()%treeBranchGrowthChance)==0){ // create new branch if((bltype[x+1+(branchTryIndex)*width]==0 )|| (bltype[x+1+(branchTryIndex)*width]==15)|| (bltype[x+1+(branchTryIndex)*width]==16)|| (bltype[x+1+(branchTryIndex)*width]==17)) { bltype[x+1+(branchTryIndex)*width]=12; architecture[x+1+(branchTryIndex)*width]=architecture_bit.dynamic; architecture[x+(branchTryIndex)*width] |= architecture_bit.bond_right; bond_hor[x+(branchTryIndex)*width]=defaultWoodBondStrength; weight[x+1+(branchTryIndex)*width]=defaultStoneBlockWeight; newBranchThisMove=1; break; } } }} // now the same for left side sideBranchFreeSpaceCounter=0; zoneStartIndex=y-minTreeBranchSpacingFromGround-1; zoneStopIndex=zoneStartIndex; if(x-1>0){ for(int trunkIndex=minTreeBranchSpacingFromGround+1; trunkIndex0){ zoneStopIndex--; } if(sideBranchFreeSpaceCounter==0){ zoneStartIndex=y-trunkIndex; zoneStopIndex=zoneStartIndex; } sideBranchFreeSpaceCounter++; }else{ sideBranchFreeSpaceCounter=0-minTreeBranchSpacing; } } if(sideBranchFreeSpaceCounter>0){ // branch-free space, can try to create branch for(int branchTryIndex=zoneStartIndex;branchTryIndex>zoneStopIndex;branchTryIndex--) if((rand()%treeBranchGrowthChance)==0){ // create new branch if((bltype[x-1+(branchTryIndex)*width]==0 )|| (bltype[x-1+(branchTryIndex)*width]==15)|| (bltype[x-1+(branchTryIndex)*width]==16)|| (bltype[x-1+(branchTryIndex)*width]==17)) { bltype[x-1+(branchTryIndex)*width]=11; architecture[x-1+(branchTryIndex)*width]=architecture_bit.dynamic; architecture[x-1+(branchTryIndex)*width] |= architecture_bit.bond_right; bond_hor[x-1+(branchTryIndex)*width]=defaultWoodBondStrength; weight[x-1+(branchTryIndex)*width]=defaultStoneBlockWeight; newBranchThisMove=1; break; } } }} } if(newBranchThisMove==0){ //right side if(x+1=width)break; if(((bltype[x+1+branchLenght+(y-onHeight)*width]==10)||(bltype[x+1+branchLenght+(y-onHeight)*width]==12))&& ((architecture[x+branchLenght+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ }else{ // branch end - can try to grow if(!((bltype[x+1+branchLenght+(y-onHeight)*width]==0 )|| (bltype[x+1+branchLenght+(y-onHeight)*width]==15)|| (bltype[x+1+branchLenght+(y-onHeight)*width]==16)|| (bltype[x+1+branchLenght+(y-onHeight)*width]==17) ))break; //branch grows! bltype[x+branchLenght+(y-onHeight)*width]=10; bltype[x+1+branchLenght+(y-onHeight)*width]=12; architecture[x+1+branchLenght+(y-onHeight)*width]=architecture_bit.dynamic; architecture[x+branchLenght+(y-onHeight)*width] |= architecture_bit.bond_right; bond_hor[x+branchLenght+(y-onHeight)*width]=defaultWoodBondStrength; weight[x+1+branchLenght+(y-onHeight)*width]=defaultStoneBlockWeight; if(branchLenght>minTreeBranchLenght){ if((rand()%treeBranchEndingChance)==0){ bltype[x+1+branchLenght+(y-onHeight)*width]=14; } } break; //enough for this branch } } } } //left side if(x-1>=0) for(int onHeight=1;onHeight<=heightReached; onHeight++){ if(((bltype[x-1+(y-onHeight)*width]==10)||(bltype[x-1+(y-onHeight)*width]==11))&& ((architecture[x-1+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ // if branch on this height for(int branchLenght=1;branchLenght<=maxTreeBranchLenght; branchLenght++){ if(x-1-branchLenght<0)break; if(((bltype[x-1-branchLenght+(y-onHeight)*width]==10)||(bltype[x-1-branchLenght+(y-onHeight)*width]==11))&& ((architecture[x-1-branchLenght+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ }else{ // branch end - can try to grow if(!((bltype[x-1-branchLenght+(y-onHeight)*width]==0 )|| (bltype[x-1-branchLenght+(y-onHeight)*width]==15)|| (bltype[x-1-branchLenght+(y-onHeight)*width]==16)|| (bltype[x-1-branchLenght+(y-onHeight)*width]==17) ))break; //branch grows! bltype[x-branchLenght+(y-onHeight)*width]=10; bltype[x-1-branchLenght+(y-onHeight)*width]=11; architecture[x-1-branchLenght+(y-onHeight)*width]=architecture_bit.dynamic; architecture[x-1-branchLenght+(y-onHeight)*width] |= architecture_bit.bond_right; bond_hor[x-1-branchLenght+(y-onHeight)*width]=defaultWoodBondStrength; weight[x-1-branchLenght+(y-onHeight)*width]=defaultStoneBlockWeight; if(branchLenght>minTreeBranchLenght){ if((rand()%treeBranchEndingChance)==0){ bltype[x-1-branchLenght+(y-onHeight)*width]=13; } } break; //enough for this branch } } } } } // grow leaves on trunk, to right if(x+10) if( (bltype[x+1+(y-onHeight-1)*width]==15)|| (bltype[x+1+(y-onHeight-1)*width]==16)|| (bltype[x+1+(y-onHeight-1)*width]==10)|| (bltype[x+1+(y-onHeight-1)*width]==11)|| (bltype[x+1+(y-onHeight-1)*width]==12)|| (bltype[x+1+(y-onHeight-1)*width]==13)|| (bltype[x+1+(y-onHeight-1)*width]==14) ){ architecture[x+1+(y-onHeight-1)*width] |= architecture_bit.bond_down; bond_ver[x+1+(y-onHeight-1)*width]=defaultWoodBondStrength; } if( (bltype[x+1+(y-onHeight+1)*width]==15)|| (bltype[x+1+(y-onHeight+1)*width]==16)|| (bltype[x+1+(y-onHeight+1)*width]==10)|| (bltype[x+1+(y-onHeight+1)*width]==11)|| (bltype[x+1+(y-onHeight+1)*width]==12)|| (bltype[x+1+(y-onHeight+1)*width]==13)|| (bltype[x+1+(y-onHeight+1)*width]==14) ){ architecture[x+1+(y-onHeight)*width] |= architecture_bit.bond_down; bond_ver[x+1+(y-onHeight)*width]=defaultWoodBondStrength; } } continue; } if((bltype[x+1+(y-onHeight)*width]==15)&& ((architecture[x+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ // if there are leaves on this height, then grow more leaves on that side for(int leavesLayer=1;leavesLayer<=maxTreeLeavesThick;leavesLayer++){ if(x+leavesLayer>width)break; if(bltype[x+leavesLayer+(y-onHeight)*width]!=15){ if(bltype[x+leavesLayer+(y-onHeight)*width]==0) if((rand()%treeLeafGrowthChance)==0){ // add one more leaf block if((rand()%treeLeafEndingChance)==0){ bltype[x+leavesLayer+(y-onHeight)*width]=16; }else{ bltype[x+leavesLayer+(y-onHeight)*width]=15; } architecture[x+leavesLayer +(y-onHeight)*width]=architecture_bit.dynamic; architecture[x+leavesLayer-1+(y-onHeight)*width] |= architecture_bit.bond_right; bond_hor [x+leavesLayer-1+(y-onHeight)*width]=defaultWoodBondStrength; weight [x+leavesLayer +(y-onHeight)*width]=defaultWoodBlockWeight; if((y-onHeight)>0) if( (bltype[x+leavesLayer+(y-onHeight-1)*width]==15)|| (bltype[x+leavesLayer+(y-onHeight-1)*width]==16)|| (bltype[x+leavesLayer+(y-onHeight-1)*width]==10)|| (bltype[x+leavesLayer+(y-onHeight-1)*width]==11)|| (bltype[x+leavesLayer+(y-onHeight-1)*width]==12)|| (bltype[x+leavesLayer+(y-onHeight-1)*width]==13)|| (bltype[x+leavesLayer+(y-onHeight-1)*width]==14) ){ architecture[x+leavesLayer+(y-onHeight-1)*width] |= architecture_bit.bond_down; bond_ver [x+leavesLayer+(y-onHeight-1)*width]=defaultWoodBondStrength; } if( (bltype[x+leavesLayer+(y-onHeight+1)*width]==15)|| (bltype[x+leavesLayer+(y-onHeight+1)*width]==16)|| (bltype[x+leavesLayer+(y-onHeight+1)*width]==10)|| (bltype[x+leavesLayer+(y-onHeight+1)*width]==11)|| (bltype[x+leavesLayer+(y-onHeight+1)*width]==12)|| (bltype[x+leavesLayer+(y-onHeight+1)*width]==13)|| (bltype[x+leavesLayer+(y-onHeight+1)*width]==14) ){ architecture[x+leavesLayer+(y-onHeight)*width] |= architecture_bit.bond_down; bond_ver [x+leavesLayer+(y-onHeight)*width]=defaultWoodBondStrength; } } break; } } } } // grow leaves on trunk, to left if(x-1>=0) for(int onHeight=2;onHeight<=heightReached; onHeight++){ if(bltype[x-1+(y-onHeight)*width]==0){ if((rand()%treeLeafGrowthChance)==0){ if((rand()%treeLeafEndingChance)==0){ bltype[x-1+(y-onHeight)*width]=16; }else{ bltype[x-1+(y-onHeight)*width]=15; } architecture[x-1+(y-onHeight)*width]=architecture_bit.dynamic; architecture[x-1+(y-onHeight)*width] |= architecture_bit.bond_right; bond_hor [x-1+(y-onHeight)*width]=defaultWoodBondStrength; weight [x-1+(y-onHeight)*width]=defaultWoodBlockWeight; if((y-onHeight)>0) if( (bltype[x-1+(y-onHeight-1)*width]==15)|| (bltype[x-1+(y-onHeight-1)*width]==16)|| (bltype[x-1+(y-onHeight-1)*width]==10)|| (bltype[x-1+(y-onHeight-1)*width]==11)|| (bltype[x-1+(y-onHeight-1)*width]==12)|| (bltype[x-1+(y-onHeight-1)*width]==13)|| (bltype[x-1+(y-onHeight-1)*width]==14) ){ architecture[x-1+(y-onHeight-1)*width] |= architecture_bit.bond_down; bond_ver [x-1+(y-onHeight-1)*width]=defaultWoodBondStrength; } if( (bltype[x-1+(y-onHeight+1)*width]==15)|| (bltype[x-1+(y-onHeight+1)*width]==16)|| (bltype[x-1+(y-onHeight+1)*width]==10)|| (bltype[x-1+(y-onHeight+1)*width]==11)|| (bltype[x-1+(y-onHeight+1)*width]==12)|| (bltype[x-1+(y-onHeight+1)*width]==13)|| (bltype[x-1+(y-onHeight+1)*width]==14) ){ architecture[x-1+(y-onHeight)*width] |= architecture_bit.bond_down; bond_ver [x-1+(y-onHeight)*width]=defaultWoodBondStrength; } } continue; } if((bltype[x-1+(y-onHeight)*width]==15)&& ((architecture[x-1+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ // if there are leaves on this height, then grow more leaves on that side for(int leavesLayer=1;leavesLayer<=maxTreeLeavesThick;leavesLayer++){ if(x-leavesLayer<0)break; if(bltype[x-leavesLayer+(y-onHeight)*width]!=15){ if(bltype[x-leavesLayer+(y-onHeight)*width]==0) if((rand()%treeLeafGrowthChance)==0){ // add one more leaf block if((rand()%treeLeafEndingChance)==0){ bltype[x-leavesLayer+(y-onHeight)*width]=16; }else{ bltype[x-leavesLayer+(y-onHeight)*width]=15; } architecture[x-leavesLayer+(y-onHeight)*width]=architecture_bit.dynamic; architecture[x-leavesLayer+(y-onHeight)*width] |= architecture_bit.bond_right; bond_hor [x-leavesLayer+(y-onHeight)*width]=defaultWoodBondStrength; weight [x-leavesLayer+(y-onHeight)*width]=defaultWoodBlockWeight; if((y-onHeight)>0) if( (bltype[x-leavesLayer+(y-onHeight-1)*width]==15)|| (bltype[x-leavesLayer+(y-onHeight-1)*width]==16)|| (bltype[x-leavesLayer+(y-onHeight-1)*width]==10)|| (bltype[x-leavesLayer+(y-onHeight-1)*width]==11)|| (bltype[x-leavesLayer+(y-onHeight-1)*width]==12)|| (bltype[x-leavesLayer+(y-onHeight-1)*width]==13)|| (bltype[x-leavesLayer+(y-onHeight-1)*width]==14) ){ architecture[x-leavesLayer+(y-onHeight-1)*width] |= architecture_bit.bond_down; bond_ver [x-leavesLayer+(y-onHeight-1)*width]=defaultWoodBondStrength; } if( (bltype[x-leavesLayer+(y-onHeight+1)*width]==15)|| (bltype[x-leavesLayer+(y-onHeight+1)*width]==16)|| (bltype[x-leavesLayer+(y-onHeight+1)*width]==10)|| (bltype[x-leavesLayer+(y-onHeight+1)*width]==11)|| (bltype[x-leavesLayer+(y-onHeight+1)*width]==12)|| (bltype[x-leavesLayer+(y-onHeight+1)*width]==13)|| (bltype[x-leavesLayer+(y-onHeight+1)*width]==14) ){ architecture[x-leavesLayer+(y-onHeight)*width] |= architecture_bit.bond_down; bond_ver [x-leavesLayer+(y-onHeight)*width]=defaultWoodBondStrength; } } break; } } } } //grow arcons, right //first - find lower branch if(x+1=width)break; if(((bltype[x+1+branchLenght+(y-onHeight)*width]==10)|| (bltype[x+1+branchLenght+(y-onHeight)*width]==12)|| (bltype[x+1+branchLenght+(y-onHeight)*width]==14) )&& ((architecture[x+branchLenght+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ if( (bltype[x+1+branchLenght+(y-onHeight+1)*width]==0 )|| (bltype[x+1+branchLenght+(y-onHeight+1)*width]==15)|| (bltype[x+1+branchLenght+(y-onHeight+1)*width]==16)) if((rand()%arconGrowthChance)==0){ bltype [x+1+branchLenght+(y-onHeight+1)*width]=17; architecture[x+1+branchLenght+(y-onHeight+1)*width]=architecture_bit.dynamic; weight [x+1+branchLenght+(y-onHeight+1)*width]=defaultStoneBlockWeight; architecture[x+1+branchLenght+(y-onHeight )*width] |= architecture_bit.bond_down; bond_ver [x+1+branchLenght+(y-onHeight )*width]=1; architecture[x +branchLenght+(y-onHeight+1)*width] &= (~architecture_bit.bond_right); bond_hor [x +branchLenght+(y-onHeight+1)*width]=0; architecture[x+1+branchLenght+(y-onHeight+1)*width] &= (~architecture_bit.bond_down); bond_ver [x+1+branchLenght+(y-onHeight+1)*width]=0; architecture[x+1+branchLenght+(y-onHeight+1)*width] &= (~architecture_bit.bond_right); bond_hor [x+1+branchLenght+(y-onHeight+1)*width]=0; break; } } } break; } //grow arcons, left //first - find lower branch if(x-1>=0) for(int onHeight=2;onHeight<=heightReached; onHeight++){ if((bltype[x-1+(y-onHeight)*width]!=10)&& (bltype[x-1+(y-onHeight)*width]!=11)&& (bltype[x-1+(y-onHeight)*width]!=13)) continue; //cycle through branch for(int branchLenght=1;branchLenght<=maxTreeBranchLenght; branchLenght++){ if(x-1-branchLenght<0)break; if(((bltype[x-1-branchLenght+(y-onHeight)*width]==10)|| (bltype[x-1-branchLenght+(y-onHeight)*width]==11)|| (bltype[x-1-branchLenght+(y-onHeight)*width]==13) )&& ((architecture[x-1-branchLenght+(y-onHeight)*width] & architecture_bit.bond_right)!=0 )){ if( (bltype[x-1-branchLenght+(y-onHeight+1)*width]==0 )|| (bltype[x-1-branchLenght+(y-onHeight+1)*width]==15)|| (bltype[x-1-branchLenght+(y-onHeight+1)*width]==16)) if((rand()%arconGrowthChance)==0){ bltype [x-1-branchLenght+(y-onHeight+1)*width]=17; architecture[x-1-branchLenght+(y-onHeight+1)*width]=architecture_bit.dynamic; weight [x-1-branchLenght+(y-onHeight+1)*width]=defaultStoneBlockWeight; architecture[x-1-branchLenght+(y-onHeight )*width] |= architecture_bit.bond_down; bond_ver [x-1-branchLenght+(y-onHeight )*width]=1; architecture[x-1-branchLenght+(y-onHeight+1)*width] &= (~architecture_bit.bond_right); bond_hor [x-1-branchLenght+(y-onHeight+1)*width]=0; architecture[x-1-branchLenght+(y-onHeight+1)*width] &= (~architecture_bit.bond_down); bond_ver [x-1-branchLenght+(y-onHeight+1)*width]=0; if(x-2-branchLenght>=0){ architecture[x-2-branchLenght+(y-onHeight+1)*width] &= (~architecture_bit.bond_right); bond_hor [x-2-branchLenght+(y-onHeight+1)*width]=0; } break; } } } break; } } if(bltype[jindex]==17){ // arcon if(y+1=0){ architecture[x-1+y * width + width] &= (~architecture_bit.bond_right); } } } } }