/* * OpenClonk, http://www.openclonk.org * * Copyright (c) 1998-2000 Matthes Bender * Copyright (c) 2001, 2005-2006 Sven Eberhardt * Copyright (c) 2005 Peter Wortmann * Copyright (c) 2005-2006, 2009 Günther Brammer * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de * * Portions might be copyrighted by other authors who have contributed * to OpenClonk. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * See isc_license.txt for full license and disclaimer. * * "Clonk" is a registered trademark of Matthes Bender. * See clonk_trademark_license.txt for full license. */ /* Move liquids in the landscape using individual transport spots */ #include #include #include #include #include #include #include #include // Note: creation optimized using advancing CreatePtr, so sequential // creation does not keep rescanning the complete set for a free // slot. (This had caused extreme delays.) This had the effect that // MMs created by another MM being executed were oftenly executed // within the same frame repetitiously leading to long distance mass // movement in no-time. To avoid this, set execution is done in // opposite direction. We now have have smoothly running masses in // a mathematical triangular shape with no delays! Since masses are // running slower and smoother, overall MM counts are much lower, // hardly ever exceeding 1000. October 1997 C4MassMoverSet::C4MassMoverSet() { Default(); } C4MassMoverSet::~C4MassMoverSet() { Clear(); } void C4MassMoverSet::Clear() { } void C4MassMoverSet::Execute() { C4MassMover *cmm; // Init counts Count=0; // Execute & count for (int32_t speed = 2; speed>0; speed--) { cmm = &(Set[C4MassMoverChunk-1]); for (int32_t cnt = 0; cntMat!=MNone) { Count++; cmm->Execute(); } } } bool C4MassMoverSet::Create(int32_t x, int32_t y, bool fExecute) { if (Count == C4MassMoverChunk) return false; #ifdef DEBUGREC C4RCMassMover rc; rc.x=x; rc.y=y; AddDbgRec(RCT_MMC, &rc, sizeof(rc)); #endif int32_t cptr=CreatePtr; do { cptr++; if (cptr>=C4MassMoverChunk) cptr=0; if (Set[cptr].Mat==MNone) { if (!Set[cptr].Init(x,y)) return false; CreatePtr=cptr; if (fExecute) Set[cptr].Execute(); return true; } } while (cptr!=CreatePtr); return false; } void C4MassMoverSet::Draw() { /*int32_t cnt; for (cnt=0; cnt(tx,0,GBackWdt-1) || !Inside(ty,0,GBackHgt-1)) return false; // Check mat Mat=GBackMat(tx,ty); x=tx; y=ty; ::MassMover.Count++; return (Mat!=MNone); } void C4MassMover::Cease() { #ifdef DEBUGREC C4RCMassMover rc; rc.x=x; rc.y=y; AddDbgRec(RCT_MMD, &rc, sizeof(rc)); #endif ::MassMover.Count--; Mat=MNone; } bool C4MassMover::Execute() { int32_t tx,ty; // Lost target material if (GBackMat(x,y)!=Mat) { Cease(); return false; } // Check for transfer target space C4Material *pMat = ::MaterialMap.Map+Mat; tx=x; ty=y; if (!::Landscape.FindMatPath(tx,ty,+1,pMat->Density,pMat->MaxSlide)) { // Contact material reaction check: corrosion/evaporation/inflammation/etc. if (Corrosion(+0,+1) || Corrosion(-1,+0) || Corrosion(+1,+0)) { // material has been used up ::Landscape.ExtractMaterial(x,y); return true; } // No space, die Cease(); return false; } // do check at this pos for conversion check /* if (Corrosion(0,0)) { // material has been used up by conversion ::Landscape.ExtractMaterial(x,y); return true; }*/ // Transfer mass int32_t mat = ::Landscape.ExtractMaterial(x,y); if (Random(10)) ::Landscape.InsertDeadMaterial(mat, tx, ty); else ::Landscape.InsertMaterial(mat, &tx, &ty, 0, 1); // modifies tx/ty to actual insertion position // Create new mover at target ::MassMover.Create(tx,ty,!Random(3)); return true; } bool C4MassMover::Corrosion(int32_t dx, int32_t dy) { // check reaction map of massmover-mat to target mat int32_t tmat=GBackMat(x+dx,y+dy); C4MaterialReaction *pReact = ::MaterialMap.GetReactionUnsafe(Mat, tmat); if (pReact) { C4Real xdir=Fix0, ydir=Fix0; if ((*pReact->pFunc)(pReact, x,y, x+dx,y+dy, xdir,ydir, Mat,tmat, meeMassMove, NULL)) return true; } return false; } void C4MassMoverSet::Default() { int32_t cnt; for (cnt=0; cnt