void StdCompilerINIRead::Byte(uint8_t &rByte) { const unsigned int MIN = 0, MAX = (1 << 8) - 1; unsigned int iNum = ReadUNum(); if (iNum > MAX) Warn("number out of range (%u to %u): %u ", MIN, MAX, iNum); rByte = BoundBy(iNum, MIN, MAX); }
void StdCompilerINIRead::Word(uint16_t &rShort) { const unsigned int MIN = 0, MAX = (1 << 15) - 1; unsigned int iNum = ReadUNum(); if (iNum > MAX) Warn("number out of range (%u to %u): %u ", MIN, MAX, iNum); rShort = BoundBy(iNum, MIN, MAX); }
void StdCompilerINIRead::Byte(int8_t &rByte) { const int MIN = -(1 << 7), MAX = (1 << 7) - 1; int iNum = ReadNum(); if (iNum < MIN || iNum > MAX) Warn("number out of range (%d to %d): %d ", MIN, MAX, iNum); rByte = BoundBy(iNum, MIN, MAX); }
void StdCompilerINIRead::Word(int16_t &rShort) { const int MIN = -(1 << 15), MAX = (1 << 15) - 1; int iNum = ReadNum(); if (iNum < MIN || iNum > MAX) Warn("number out of range (%d to %d): %d ", MIN, MAX, iNum); rShort = BoundBy(iNum, MIN, MAX); }
global func FxFireScorchingTimer(object target, proplist effect, int time) { if (time >= effect.duration) { RemoveObject(); return FX_Execute_Kill; } // particles var wind = BoundBy(GetWind(), -5, 5); CreateParticle("SmokeDirty", PV_Random(-5, 5), PV_Random(-5, 5), wind, -effect.strength/8, PV_Random(20, 40), Particles_SmokeTrail(), 2); return FX_OK; }
global func FireBreathReach(proplist info) { info.time += 1; if (info.time <= CYCLOPS_FireBreath_Duration) { var v = ((CYCLOPS_FireBreath_Duration - info.time) * info.v0 + info.time * info.v1) / CYCLOPS_FireBreath_Duration; info.reach = BoundBy(info.reach + v, 0, info.rmax); } }
protected func CheckBorders() { // Prüfen ob ein Objekt gerade aus dem Spielfeld fliegt var mapwdt = LandscapeWidth(); var xdir, xoff, x; for (var obj in FindObjects(Find_Func("GetXDir"))) { xdir = GetXDir(obj)/10; xoff = obj->GetDefOffset(); if (xdir < 0) { // Linker Rand x = (GetX(obj)+xoff)+xdir; if (x <= 0) SetPosition(BoundBy(mapwdt+x-xoff, 0, mapwdt+xoff), GetY(obj)+GetYDir(obj)/10, obj, 1); } else { // Rechter Rand x = (GetX(obj)-xoff)+xdir-mapwdt; if (x >= 0) SetPosition(BoundBy(x+xoff, -xoff, mapwdt), GetY(obj)+GetYDir(obj)/10, obj, 1); } } return 1; }
void C4SoundInstance::Execute() { // Object deleted? if (pObj && !pObj->Status) ClearPointers(pObj); // initial values int32_t iVol = iVolume * 256 * Config.Sound.SoundVolume / 100, iPan = C4SoundInstance::iPan; // bound to an object? if (pObj) { int iAudibility = pObj->Audible; // apply custom falloff distance if (iFalloffDistance) { iAudibility = BoundBy<int32_t>( 100 + (iAudibility - 100) * C4AudibilityRadius / iFalloffDistance, 0, 100); } iVol = iVol * iAudibility / 100; iPan += pObj->AudiblePan; } // sound off? if (!iVol) { // stop, if started if (isStarted()) { #ifdef HAVE_LIBSDL_MIXER Mix_HaltChannel(iChannel); #endif iChannel = -1; } } else { // start if (!isStarted()) if (!CheckStart()) return; // set volume & panning #ifdef HAVE_LIBSDL_MIXER Mix_Volume(iChannel, (iVol * MIX_MAX_VOLUME) / (100 * 256)); // Mix_SetPanning(iChannel, ((100 + iPan) * 256) / 200, ((100 - iPan) * 256) // / 200); Mix_SetPanning(iChannel, BoundBy((100 - iPan) * 256 / 100, 0, 255), BoundBy((100 + iPan) * 256 / 100, 0, 255)); #endif } }
private func Wind2Turn() { // Zielobjekt verloren if (!GetActionTarget()) return(RemoveObject()); // Drehgeschwindigkeit var turn = BoundBy(GetWind()/20 +5, 1, 9); if(!(GetAction() eq Format("Turn%d", turn))) SetAction(Format("Turn%d", turn)); // Energieerzeugung DoEnergy(GetActMapVal("Delay", Format("Turn%d", turn))*30, GetActionTarget()); }
bool StdMeshUpdate::UpdateAnimationNode(StdMeshInstance* instance, const StdMesh& new_mesh, StdMeshInstance::AnimationNode* node) const { switch (node->GetType()) { case StdMeshInstance::AnimationNode::LeafNode: { // Find dead animation std::map<const StdMeshAnimation*, StdCopyStrBuf>::const_iterator iter = AnimationNames.find(node->Leaf.Animation); assert(iter != AnimationNames.end()); // Update to new animation node->Leaf.Animation = new_mesh.GetSkeleton().GetAnimationByName(iter->second); if(!node->Leaf.Animation) return false; // Clamp provider value StdMeshInstance::ValueProvider* provider = node->GetPositionProvider(); C4Real min = Fix0; C4Real max = ftofix(node->GetAnimation()->Length); provider->Value = BoundBy(provider->Value, min, max); return true; } case StdMeshInstance::AnimationNode::CustomNode: { // Update bone index by bone name StdCopyStrBuf bone_name = BoneNamesByIndex[node->Custom.BoneIndex]; const StdMeshBone* bone = new_mesh.GetSkeleton().GetBoneByName(bone_name); if(!bone) return false; node->Custom.BoneIndex = bone->Index; return true; } case StdMeshInstance::AnimationNode::LinearInterpolationNode: { const bool left_result = UpdateAnimationNode(instance, new_mesh, node->GetLeftChild()); const bool right_result = UpdateAnimationNode(instance, new_mesh, node->GetRightChild()); // Remove this node completely if (!left_result && !right_result) return false; // Note that either of this also removes this node (and replaces by // the other child in the tree). if (!left_result) instance->StopAnimation(node->GetLeftChild()); if (!right_result) instance->StopAnimation(node->GetRightChild()); return true; } default: assert(false); return false; } }
void Explosion(int32_t tx, int32_t ty, int32_t level, C4Object *inobj, int32_t iCausedBy, C4Object *pByObj, C4ID idEffect, const char *szEffect) { int32_t grade = BoundBy((level / 10) - 1, 1, 3); // Sound StdStrBuf sound = FormatString("Blast%c", '0' + grade); StartSoundEffect(sound.getData(), false, 100, pByObj); // Check blast containment C4Object *container = inobj; while (container && !container->Def->ContainBlast) container = container->Contained; // Uncontained blast effects if (!container) { // Incinerate landscape if (!Game.Landscape.Incinerate(tx, ty)) if (!Game.Landscape.Incinerate(tx, ty - 10)) if (!Game.Landscape.Incinerate(tx - 5, ty - 5)) Game.Landscape.Incinerate(tx + 5, ty - 5); // Create blast object or particle C4Object *pBlast; C4ParticleDef *pPrtDef = Game.Particles.pBlast; // particle override if (szEffect) { C4ParticleDef *pPrtDef2 = Game.Particles.GetDef(szEffect); if (pPrtDef2) pPrtDef = pPrtDef2; } else if (idEffect) pPrtDef = NULL; // create particle if (pPrtDef) { Game.Particles.Create(pPrtDef, (float)tx, (float)ty, 0.0f, 0.0f, (float)level, 0); if (SEqual2(pPrtDef->Name.getData(), "Blast")) Game.Particles.Cast(Game.Particles.pFSpark, level / 5 + 1, (float)tx, (float)ty, level, level / 2 + 1.0f, 0x00ef0000, level + 1.0f, 0xffff1010); } else if (pBlast = Game.CreateObjectConstruction( idEffect ? idEffect : C4Id("FXB1"), pByObj, iCausedBy, tx, ty + level, FullCon * level / 20)) pBlast->Call(PSF_Activate); } // Blast objects Game.BlastObjects(tx, ty, level, inobj, iCausedBy, pByObj); if (container != inobj) Game.BlastObjects(tx, ty, level, container, iCausedBy, pByObj); if (!container) { // Blast free landscape. After blasting objects so newly mined materials // don't get flinged Game.Landscape.BlastFree(tx, ty, level, grade, iCausedBy); } }
private func CheckStuck() { var pClonk,iYChange,iX,iY; // Alle feststeckenden Clonks in der Nähe suchen for (pClonk in FindObjects(Find_InRect(-20,-20,40,40), Find_OCF(OCF_CrewMember),Find_NoContainer())) { iX=GetX(pClonk); iY=GetY(pClonk); while(Stuck(pClonk) && Inside(GetY(pClonk)-GetY(),-20,20)) { if(!(iYChange=BoundBy(GetY(pClonk)-GetY(),-1,1))) iYChange=1; // Zur Sicherheit... if(!Inside(GetY(pClonk)+iYChange,-100,LandscapeHeight())) break; SetPosition(GetX(pClonk),GetY(pClonk)+iYChange,pClonk); } // verschieben fehlgeschlagen: rückgängig machen if(Stuck(pClonk)) SetPosition(iX,iY,pClonk); } }
bool C4MessageInput::ProcessCommand(const char *szCommand) { C4GameLobby::MainDlg *pLobby = Game.Network.GetLobby(); // command char szCmdName[C4MaxName + 1]; SCopyUntil(szCommand + 1, szCmdName, ' ', C4MaxName); // parameter const char *pCmdPar = SSearch(szCommand, " "); if (!pCmdPar) pCmdPar = ""; // dev-scripts if (SEqual(szCmdName, "help")) { LogF(LoadResStr("IDS_TEXT_COMMANDSAVAILABLEDURINGGA")); LogF("/private [player] [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOTHES")); LogF("/team [message] - %s", LoadResStr("IDS_MSG_SENDAPRIVATEMESSAGETOYOUR")); LogF("/me [action] - %s", LoadResStr("IDS_TEXT_PERFORMANACTIONINYOURNAME")); LogF("/sound [sound] - %s", LoadResStr("IDS_TEXT_PLAYASOUNDFROMTHEGLOBALSO")); LogF("/kick [client] - %s", LoadResStr("IDS_TEXT_KICKTHESPECIFIEDCLIENT")); LogF("/observer [client] - %s", LoadResStr("IDS_TEXT_SETTHESPECIFIEDCLIENTTOOB")); LogF("/fast [x] - %s", LoadResStr("IDS_TEXT_SETTOFASTMODESKIPPINGXFRA")); LogF("/slow - %s", LoadResStr("IDS_TEXT_SETTONORMALSPEEDMODE")); LogF("/chart - %s", LoadResStr("IDS_TEXT_DISPLAYNETWORKSTATISTICS")); LogF("/nodebug - %s", LoadResStr("IDS_TEXT_PREVENTDEBUGMODEINTHISROU")); LogF("/set comment [comment] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKCOMMENT")); LogF("/set password [password] - %s", LoadResStr("IDS_TEXT_SETANEWNETWORKPASSWORD")); LogF("/set faircrew [on/off] - %s", LoadResStr("IDS_TEXT_ENABLEORDISABLEFAIRCREW")); LogF("/set maxplayer [4] - %s", LoadResStr("IDS_TEXT_SETANEWMAXIMUMNUMBEROFPLA")); LogF("/script [script] - %s", LoadResStr("IDS_TEXT_EXECUTEASCRIPTCOMMAND")); LogF("/clear - %s", LoadResStr("IDS_MSG_CLEARTHEMESSAGEBOARD")); return TRUE; } // dev-scripts if (SEqual(szCmdName, "script")) { if (!Game.IsRunning) return FALSE; if (!Game.DebugMode) return FALSE; if (!Game.Network.isEnabled() && !SEqual(Game.ScenarioFile.GetMaker(), Config.General.Name) && Game.ScenarioFile.GetStatus() != GRPF_Folder) return FALSE; if (Game.Network.isEnabled() && !Game.Network.isHost()) return FALSE; Game.Control.DoInput( CID_Script, new C4ControlScript(pCmdPar, C4ControlScript::SCOPE_Console, false), CDT_Decide); return TRUE; } // set runtimte properties if (SEqual(szCmdName, "set")) { if (SEqual2(pCmdPar, "maxplayer ")) { if (Game.Control.isCtrlHost()) { if (atoi(pCmdPar + 10) == 0 && !SEqual(pCmdPar + 10, "0")) { Log("Syntax: /set maxplayer count"); return FALSE; } Game.Control.DoInput( CID_Set, new C4ControlSet(C4CVT_MaxPlayer, atoi(pCmdPar + 10)), CDT_Decide); return TRUE; } } if (SEqual2(pCmdPar, "comment ") || SEqual(pCmdPar, "comment")) { if (!Game.Network.isEnabled() || !Game.Network.isHost()) return FALSE; // Set in configuration, update reference Config.Network.Comment.CopyValidated(pCmdPar[7] ? (pCmdPar + 8) : ""); Game.Network.InvalidateReference(); Log(LoadResStr("IDS_NET_COMMENTCHANGED")); return TRUE; } if (SEqual2(pCmdPar, "password ") || SEqual(pCmdPar, "password")) { if (!Game.Network.isEnabled() || !Game.Network.isHost()) return FALSE; Game.Network.SetPassword(pCmdPar[8] ? (pCmdPar + 9) : NULL); if (pLobby) pLobby->UpdatePassword(); return TRUE; } if (SEqual2(pCmdPar, "faircrew ")) { if (!Game.Control.isCtrlHost() || Game.Parameters.isLeague()) return FALSE; C4ControlSet *pSet = NULL; if (SEqual(pCmdPar + 9, "on")) pSet = new C4ControlSet(C4CVT_FairCrew, Config.General.FairCrewStrength); else if (SEqual(pCmdPar + 9, "off")) pSet = new C4ControlSet(C4CVT_FairCrew, -1); else if (isdigit((unsigned char)pCmdPar[9])) pSet = new C4ControlSet(C4CVT_FairCrew, atoi(pCmdPar + 9)); else return FALSE; Game.Control.DoInput(CID_Set, pSet, CDT_Decide); return TRUE; } // unknown property return FALSE; } // get szen from network folder - not in lobby; use res tab there if (SEqual(szCmdName, "netgetscen")) { if (Game.Network.isEnabled() && !Game.Network.isHost() && !pLobby) { const C4Network2ResCore *pResCoreScen = Game.Parameters.Scenario.getResCore(); if (pResCoreScen) { C4Network2Res::Ref pScenario = Game.Network.ResList.getRefRes(pResCoreScen->getID()); if (pScenario) if (C4Group_CopyItem( pScenario->getFile(), Config.AtExePath(GetFilename(Game.ScenarioFilename)))) { LogF(LoadResStr("IDS_MSG_CMD_NETGETSCEN_SAVED"), Config.AtExePath(GetFilename(Game.ScenarioFilename))); return TRUE; } } } return FALSE; } // clear message board if (SEqual(szCmdName, "clear")) { // lobby if (pLobby) { pLobby->ClearLog(); } // fullscreen else if (Game.GraphicsSystem.MessageBoard.Active) Game.GraphicsSystem.MessageBoard.ClearLog(); else { // EM mode Console.ClearLog(); } return TRUE; } // kick client if (SEqual(szCmdName, "kick")) { if (Game.Network.isEnabled() && Game.Network.isHost()) { // find client C4Client *pClient = Game.Clients.getClientByName(pCmdPar); if (!pClient) { LogF(LoadResStr("IDS_MSG_CMD_NOCLIENT"), pCmdPar); return FALSE; } // league: Kick needs voting if (Game.Parameters.isLeague() && Game.Players.GetAtClient(pClient->getID())) Game.Network.Vote(VT_Kick, true, pClient->getID()); else // add control Game.Clients.CtrlRemove(pClient, LoadResStr("IDS_MSG_KICKFROMMSGBOARD")); } return TRUE; } // set fast mode if (SEqual(szCmdName, "fast")) { if (!Game.IsRunning) return FALSE; if (Game.Parameters.isLeague()) { Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE")); return FALSE; } int32_t iFS; if ((iFS = atoi(pCmdPar)) == 0) return FALSE; // set frameskip and fullspeed flag Game.FrameSkip = BoundBy<int32_t>(iFS, 1, 500); Game.FullSpeed = TRUE; // start calculation immediatly Application.NextTick(false); return TRUE; } // reset fast mode if (SEqual(szCmdName, "slow")) { if (!Game.IsRunning) return FALSE; Game.FullSpeed = FALSE; Game.FrameSkip = 1; return TRUE; } if (SEqual(szCmdName, "nodebug")) { if (!Game.IsRunning) return FALSE; Game.Control.DoInput(CID_Set, new C4ControlSet(C4CVT_AllowDebug, false), CDT_Decide); return TRUE; } if (SEqual(szCmdName, "msgboard")) { if (!Game.IsRunning) return FALSE; // get line cnt int32_t iLineCnt = BoundBy(atoi(pCmdPar), 0, 20); if (iLineCnt == 0) Game.GraphicsSystem.MessageBoard.ChangeMode(2); else if (iLineCnt == 1) Game.GraphicsSystem.MessageBoard.ChangeMode(0); else { Game.GraphicsSystem.MessageBoard.iLines = iLineCnt; Game.GraphicsSystem.MessageBoard.ChangeMode(1); } return TRUE; } // kick/activate/deactivate/observer if (SEqual(szCmdName, "activate") || SEqual(szCmdName, "deactivate") || SEqual(szCmdName, "observer")) { if (!Game.Network.isEnabled() || !Game.Network.isHost()) { Log(LoadResStr("IDS_MSG_CMD_HOSTONLY")); return FALSE; } // search for client C4Client *pClient = Game.Clients.getClientByName(pCmdPar); if (!pClient) { LogF(LoadResStr("IDS_MSG_CMD_NOCLIENT"), pCmdPar); return FALSE; } // what to do? C4ControlClientUpdate *pCtrl = NULL; if (szCmdName[0] == 'a') // activate pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_Activate, true); else if (szCmdName[0] == 'd' && !Game.Parameters.isLeague()) // deactivate pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_Activate, false); else if (szCmdName[0] == 'o' && !Game.Parameters.isLeague()) // observer pCtrl = new C4ControlClientUpdate(pClient->getID(), CUT_SetObserver); // perform it if (pCtrl) Game.Control.DoInput(CID_ClientUpdate, pCtrl, CDT_Sync); else Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE")); return TRUE; } // control mode if (SEqual(szCmdName, "centralctrl") || SEqual(szCmdName, "decentralctrl") || SEqual(szCmdName, "asyncctrl")) { if (!Game.Network.isEnabled() || !Game.Network.isHost()) { Log(LoadResStr("IDS_MSG_CMD_HOSTONLY")); return FALSE; } if (Game.Parameters.isLeague() && *szCmdName == 'a') { Log(LoadResStr("IDS_LOG_COMMANDNOTALLOWEDINLEAGUE")); return FALSE; } Game.Network.SetCtrlMode( *szCmdName == 'c' ? CNM_Central : *szCmdName == 'd' ? CNM_Decentral : CNM_Async); return TRUE; } // show chart if (Game.IsRunning) if (SEqual(szCmdName, "chart")) return Game.ToggleChart(); // custom command C4MessageBoardCommand *pCmd; if (Game.IsRunning) if (pCmd = GetCommand(szCmdName)) { StdStrBuf Script, CmdScript; // replace %player% by calling player number if (SSearch(pCmd->Script, "%player%")) { int32_t iLocalPlr = NO_OWNER; C4Player *pLocalPlr = Game.Players.GetLocalByIndex(0); if (pLocalPlr) iLocalPlr = pLocalPlr->Number; StdStrBuf sLocalPlr; sLocalPlr.Format("%d", iLocalPlr); CmdScript.Copy(pCmd->Script); CmdScript.Replace("%player%", sLocalPlr.getData()); } else { CmdScript.Ref(pCmd->Script); } // insert parameters if (SSearch(CmdScript.getData(), "%d")) { // make sure it's a number by converting Script.Format(CmdScript.getData(), (int)atoi(pCmdPar)); } else if (SSearch(CmdScript.getData(), "%s")) { // Unrestricted parameters? // That's kind of a security risk as it will allow anyone to execute // code switch (pCmd->eRestriction) { case C4MessageBoardCommand::C4MSGCMDR_Escaped: { // escape strings StdStrBuf Par; Par.Copy(pCmdPar); Par.EscapeString(); // compose script Script.Format(CmdScript.getData(), Par.getData()); } break; case C4MessageBoardCommand::C4MSGCMDR_Plain: // unescaped Script.Format(CmdScript.getData(), pCmdPar); break; case C4MessageBoardCommand::C4MSGCMDR_Identifier: { // only allow identifier-characters StdStrBuf Par; while (IsIdentifier(*pCmdPar) || isspace((unsigned char)*pCmdPar)) Par.AppendChar(*pCmdPar++); // compose script Script.Format(CmdScript.getData(), Par.getData()); } break; } } else Script = CmdScript.getData(); // add script Game.Control.DoInput(CID_Script, new C4ControlScript(Script.getData()), CDT_Decide); // ok return TRUE; } // unknown command StdStrBuf sErr; sErr.Format(LoadResStr("IDS_ERR_UNKNOWNCMD"), szCmdName); if (pLobby) pLobby->OnError(sErr.getData()); else Log(sErr.getData()); return FALSE; }
void C4MusicFileMID::SetVolume(int iLevel) { FMUSIC_SetMasterVolume(mod, BoundBy((iLevel * 256) / 100, 0, 255)); }
global func Explode(int iLevel, object pObj, id idEffect, string szEffect) { if(!pObj) if(!(pObj=this)) return; var x = AbsX(pObj->GetX()), y = AbsY(pObj->GetY()); var boom = FindObject(BOOM); if(!boom) boom = CreateObject(BOOM,0,0,-1); var xdir = GetXDir(pObj) + GetWind(GetX(pObj),GetY(pObj))/20; var ydir = GetYDir(pObj); var opt_angle = Angle(xdir,ydir); var speed = BoundBy(Distance(xdir,ydir),0,60); ///Feuer-, Funken- und Dirt-Effekte... var i=0, count = 3+iLevel/8, angle = Random(360); while((count > 0) && (++i < count*10)) { angle += RandomX(40,80); angle = Interpolate4K(angle,opt_angle,0,60,speed); angle -= 180; //Rauch var smokex = +Sin(angle,RandomX(iLevel/4,iLevel/2)); var smokey = -Cos(angle,RandomX(iLevel/4,iLevel/2)); if(GBackSolid(x+smokex,y+smokey)) continue; var level = iLevel + Random(iLevel/5); var a = angle+RandomX(-15,+15); for(var i = 7; i > 0; i--) CreateParticle("BlastSpark1", smokex, smokey, +Sin(a,level+RandomX(-5,+5)), -Cos(a,level+RandomX(-5,+5)), 25+Random(50)); CreateParticle("BlastFlame", smokex, smokey, +Sin(angle,level/2), -Cos(angle,level/2), level*5); for(var i = Random(3)+1; i > 0; i--) { a = angle+RandomX(-30,+30); CreateParticle("BlastDirt", smokex, smokey, +Sin(a,level+RandomX(-20,+20)), -Cos(a,level+RandomX(-20,+20)), level*RandomX(7,12)); } //CreateSmokeTrail(level,angle,smokex,smokey,pObj); count--; } ///Brandspuren... // Wir haben keine Effekteinstellungen oä., daher immer an //if(EffectLevel() > EM4K_Low) CreateBurnMark(x,y,iLevel,20+iLevel/2); ///Lichteffekte bei Dunkelheit... if(IsDark()) { var iSize = iLevel*100; if(iLevel < 20) iSize /= 2; AddLightFlash(iSize/3, x, y, RGBa(255,220,64,15)); } ///Feuer-Effekt.. /*angle = Interpolate4K(0,opt_angle,0,120,speed); angle -= 180; CreateParticle("BlastBg",0,0,+Sin(angle,100),-Cos(angle,100),iLevel*20); //CreateParticle("BlastBg",0,0,0,-1,iLevel*20); */ ///Der eigentliche Blast-Partikel... CreateParticle("Blast",x,y,0,0,iLevel*11); ///Standart-Verhalten... return inherited(iLevel, pObj, idEffect, szEffect); }
C4FindObject *C4FindObject::CreateByValue(const C4Value &DataVal, C4SortObject **ppSortObj) { // Must be an array C4ValueArray *pArray = C4Value(DataVal).getArray(); if (!pArray) return NULL; const C4ValueArray &Data = *pArray; int32_t iType = Data[0].getInt(); if (Inside<int32_t>(iType, C4SO_First, C4SO_Last)) { // this is not a FindObject but a sort condition! // sort condition not desired here? if (!ppSortObj) return NULL; // otherwise, create it! *ppSortObj = C4SortObject::CreateByValue(iType, Data); // done return NULL; } switch (iType) { case C4FO_Not: { // Create child condition C4FindObject *pCond = C4FindObject::CreateByValue(Data[1]); if (!pCond) return NULL; // wrap return new C4FindObjectNot(pCond); } case C4FO_And: case C4FO_Or: { // Trivial case (one condition) if (Data.GetSize() == 2) return C4FindObject::CreateByValue(Data[1]); // Create all childs int32_t i; C4FindObject **ppConds = new C4FindObject *[Data.GetSize() - 1]; for (i = 0; i < Data.GetSize() - 1; i++) ppConds[i] = C4FindObject::CreateByValue(Data[i + 1]); // Count real entries, move them to start of list int32_t iSize = 0; for (i = 0; i < Data.GetSize() - 1; i++) if (ppConds[i]) if (iSize++ != i) ppConds[iSize - 1] = ppConds[i]; // Create if (iType == C4FO_And) return new C4FindObjectAnd(iSize, ppConds); else return new C4FindObjectOr(iSize, ppConds); } case C4FO_Exclude: return new C4FindObjectExclude(Data[1].getObj()); case C4FO_ID: return new C4FindObjectID(Data[1].getC4ID()); case C4FO_InRect: return new C4FindObjectInRect(C4Rect(Data[1].getInt(), Data[2].getInt(), Data[3].getInt(), Data[4].getInt())); case C4FO_AtPoint: return new C4FindObjectAtPoint(Data[1].getInt(), Data[2].getInt()); case C4FO_AtRect: return new C4FindObjectAtRect(Data[1].getInt(), Data[2].getInt(), Data[3].getInt(), Data[4].getInt()); case C4FO_OnLine: return new C4FindObjectOnLine(Data[1].getInt(), Data[2].getInt(), Data[3].getInt(), Data[4].getInt()); case C4FO_Distance: return new C4FindObjectDistance(Data[1].getInt(), Data[2].getInt(), Data[3].getInt()); case C4FO_OCF: return new C4FindObjectOCF(Data[1].getInt()); case C4FO_Category: return new C4FindObjectCategory(Data[1].getInt()); case C4FO_Action: { C4String *pStr = Data[1].getStr(); if (!pStr) return NULL; // Don't copy, it should be safe return new C4FindObjectAction(pStr->Data.getData()); } case C4FO_Func: { // Get function name C4String *pStr = Data[1].getStr(); if (!pStr) return NULL; // Construct C4FindObjectFunc *pFO = new C4FindObjectFunc(pStr->Data.getData()); // Add parameters for (int i = 2; i < Data.GetSize(); i++) pFO->SetPar(i - 2, Data[i]); // Done return pFO; } case C4FO_ActionTarget: { int index = 0; if (Data.GetSize() >= 3) index = BoundBy(Data[2].getInt(), 0, 1); return new C4FindObjectActionTarget(Data[1].getObj(), index); } case C4FO_Container: return new C4FindObjectContainer(Data[1].getObj()); case C4FO_AnyContainer: return new C4FindObjectAnyContainer(); case C4FO_Owner: return new C4FindObjectOwner(Data[1].getInt()); case C4FO_Controller: return new C4FindObjectController(Data[1].getInt()); case C4FO_Layer: return new C4FindObjectLayer(Data[1].getObj()); } return NULL; }
int32_t C4SVal::Evaluate() { return BoundBy(Std+Random(2*Rnd+1)-Rnd,Min,Max); }
func SetCharge(int to) { power_seconds = BoundBy(to, 0, Compensator_max_seconds); RefreshAnimationPosition(); }
func Finished() { Log("All nuggets collected!"); GainScenarioAchievement("Done", BoundBy(SCENPAR_Difficulty, 1, 3)); GameOver(); }
void C4MapCreator::Create(CSurface8 *sfcMap, C4SLandscape &rLScape, C4TextureMap &rTexMap, BOOL fLayers, int32_t iPlayerNum) { double fullperiod = 20.0 * pi; BYTE ccol; int32_t cx, cy; // Safeties if (!sfcMap) return; iPlayerNum = BoundBy<int32_t>(iPlayerNum, 1, C4S_MaxPlayer); // Set creator variables MapBuf = sfcMap; MapWdt = MapBuf->Wdt; MapHgt = MapBuf->Hgt; // Reset map (0 is sky) MapBuf->ClearBox8Only(0, 0, MapBuf->Wdt, MapBuf->Hgt); // Surface ccol = rTexMap.GetIndexMatTex(rLScape.Material, "Smooth") + MapIFT; float amplitude = (float)rLScape.Amplitude.Evaluate(); float phase = (float)rLScape.Phase.Evaluate(); float period = (float)rLScape.Period.Evaluate(); if (rLScape.MapPlayerExtend) period *= Min(iPlayerNum, C4S_MaxMapPlayerExtend); float natural = (float)rLScape.Random.Evaluate(); int32_t level0 = Min(MapWdt, MapHgt) / 2; int32_t maxrange = level0 * 3 / 4; double cy_curve, cy_natural; // -1.0 - +1.0 ! double rnd_cy, rnd_tend; // -1.0 - +1.0 ! rnd_cy = (double)(Random(2000 + 1) - 1000) / 1000.0; rnd_tend = (double)(Random(200 + 1) - 100) / 20000.0; for (cx = 0; cx < MapWdt; cx++) { rnd_cy += rnd_tend; rnd_tend += (double)(Random(100 + 1) - 50) / 10000; if (rnd_tend > +0.05) rnd_tend = +0.05; if (rnd_tend < -0.05) rnd_tend = -0.05; if (rnd_cy < -0.5) rnd_tend += 0.01; if (rnd_cy > +0.5) rnd_tend -= 0.01; cy_natural = rnd_cy * natural / 100.0; cy_curve = sin(fullperiod * period / 100.0 * (float)cx / (float)MapWdt + 2.0 * pi * phase / 100.0) * amplitude / 100.0; cy = level0 + BoundBy((int32_t)((float)maxrange * (cy_curve + cy_natural)), -maxrange, +maxrange); SetPix(cx, cy, ccol); } // Raise bottom to surface for (cx = 0; cx < MapWdt; cx++) for (cy = MapHgt - 1; (cy >= 0) && !GetPix(cx, cy); cy--) SetPix(cx, cy, ccol); // Raise liquid level Exclusive = 0; ccol = rTexMap.GetIndexMatTex(rLScape.Liquid, "Smooth"); int32_t wtr_level = rLScape.LiquidLevel.Evaluate(); for (cx = 0; cx < MapWdt; cx++) for (cy = MapHgt * (100 - wtr_level) / 100; cy < MapHgt; cy++) SetPix(cx, cy, ccol); Exclusive = -1; // Layers if (fLayers) { // Base material Exclusive = rTexMap.GetIndexMatTex(rLScape.Material, "Smooth") + MapIFT; int32_t cnt, clayer, layer_num, sptx, spty; // Process layer name list for (clayer = 0; clayer < C4MaxNameList; clayer++) if (rLScape.Layers.Name[clayer][0]) { // Draw layers ccol = rTexMap.GetIndexMatTex(rLScape.Layers.Name[clayer], "Rough") + MapIFT; layer_num = rLScape.Layers.Count[clayer]; layer_num = layer_num * MapWdt * MapHgt / 15000; for (cnt = 0; cnt < layer_num; cnt++) { // Place layer sptx = Random(MapWdt); for (spty = 0; (spty < MapHgt) && (GetPix(sptx, spty) != Exclusive); spty++) ; spty += 5 + Random((MapHgt - spty) - 10); DrawLayer(sptx, spty, Random(15), ccol); } } Exclusive = -1; } }
void CSurface8::Clip(int iX, int iY, int iX2, int iY2) { ClipX=BoundBy(iX,0,Wdt-1); ClipY=BoundBy(iY,0,Hgt-1); ClipX2=BoundBy(iX2,0,Wdt-1); ClipY2=BoundBy(iY2,0,Hgt-1); }