-- -- manureTrigger -- Specialization for manureTrigger -- -- @author Felix "Outlaw" Sorge -- @date 20/05/09 -- @web www.ls-modsource.de - www.ls-mods.de -- -- Copyright (C) Outlaw, All Rights Reserved. -- manureTrigger = {}; function manureTrigger.prerequisitesPresent(specializations) return SpecializationUtil.hasSpecialization(Trailer, specializations); end; function manureTrigger:load(xmlFile) self.manureInLowRange = SpecializationUtil.callSpecializationsFunction("manureInLowRange"); self.manureInArmRange = SpecializationUtil.callSpecializationsFunction("manureInArmRange"); self.farmerInRange = SpecializationUtil.callSpecializationsFunction("farmerInRange"); self.connectCollisions = SpecializationUtil.callSpecializationsFunction("connectCollisions"); self.anim = SpecializationUtil.callSpecializationsFunction("anim"); self.Go = {}; self.Done = {}; self.charId = {}; self.clipIndex = {}; self.CheckDone = {}; self.moveColli = {}; self.animParts = {} self.collisionArm = {}; local count = getXMLInt(xmlFile, "vehicle.animParts#count"); local part = self.animParts; for i=1, count do part[i] = {}; local partname = string.format("vehicle.animParts.part".."%d", i); local nameR = getXMLString(xmlFile, partname.."#name"); self.charId[nameR] = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.."#rootNode")); self.clipIndex[nameR] = getXMLString(xmlFile, partname.."#animationClip"); self.CheckDone[nameR] = false; self.moveColli[nameR] = getXMLString(xmlFile, partname.."#moveColli"); if self.moveColli[nameR] ~= nil then local Collision = {}; Collision.collision = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.."#collision")); Collision.collisionAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.."#collsionAttacher")); Collision.armAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.. "#armAttacher")); Collision.index = 0; self.collisionArm[nameR] = Collision; self:connectCollisions(nameR); end; end; self.pricePerLiter = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pricePerLiter#value"), 0.05); self.literPerQm = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerQm#value"), 0.01); self.literPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerSecond#value"), 1); self.fillPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillPerSecond#value"), 1); self.checkType = getXMLString(xmlFile, "vehicle.fillTypes#fruitTypes"); self.fillLowNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fillNode#lower")); self.fillArmNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fillNode#arm")); self.comp1Node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.comp1Node#index")); self.comp0Node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.comp0Node#index")); self.palletNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.palletNode#index")); self.buildNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.buildNode#index")); self.compLink = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.compLink#index")); self.modus = 0; self.keyType = InputBinding.getButtonKeyName; self.keyName = "Taste"; if self.fillLevel == 0 or self.fillLevel == nil then self:setFillLevel(1, FruitUtil.FRUITTYPE_MANURE); end; end; function manureTrigger:update(dt) if self.modus == 0 then -- nur palette / only palett setVisibility(self.comp1Node, false); setVisibility(self.buildNode, false); setVisibility(self.palletNode, true); setCollisionMask(self.comp1Node, 0) setRigidBodyType(self.comp1Node, "None"); link(self.compLink, self.comp1Node); setTranslation(self.comp1Node, 0,0,0) setRotation(self.comp1Node, 0,0,0) elseif self.modus == 1 then -- platte weg und bauansicht / without palett only buildplan setVisibility(self.buildNode, true); setVisibility(self.palletNode, false); elseif self.modus == 2 then -- aufbau / buliding... setCollisionMask(self.comp1Node, 2102) setRigidBodyType(self.comp1Node, "Kinematic"); setCollisionMask(self.comp0Node, 0) setRigidBodyType(self.comp0Node, "None"); if not self.Go.build then self.Go.build = not self.Go.build; self.Done.build = true; end; elseif self.modus == 3 then -- trigger ist aufgebaut mit fuellfunktion / build done - fill works if not self.firstRun then self.firstRun = true; FruitUtil.fruitIndexToDesc[self.currentFillType].pricePerLiter = self.pricePerLiter; FruitUtil.fruitIndexToDesc[self.currentFillType].literPerQm = self.literPerQm; setVisibility(self.buildNode, false); setVisibility(self.comp1Node, true); setVisibility(self.palletNode, false); setCollisionMask(self.comp1Node, 0) setRigidBodyType(self.comp1Node, "None"); link(self.compLink, self.comp1Node); setTranslation(self.comp1Node, 0,0,0) setRotation(self.comp1Node, 0,0,0) setCollisionMask(self.comp1Node, 2102) setRigidBodyType(self.comp1Node, "Kinematic"); setCollisionMask(self.comp0Node, 0) setRigidBodyType(self.comp0Node, "None"); end; local newFill = self.fillPerSecond*dt/1000.0 self:setFillLevel(self.fillLevel + newFill, FruitUtil.FRUITTYPE_MANURE); self:manureInLowRange(dt); self:manureInArmRange(dt); elseif self.modus == 4 then -- wieder einpacken, wurde schon ausgeführt / rebuild setVisibility(self.buildNode, true); g_currentMission:addExtraPrintText(g_i18n:getText("manureTrigger_6")); end; if self.CheckDone.build then -- aufbau fertig / build done self.modus = 3; setVisibility(self.buildNode, false); setVisibility(self.comp1Node, true); end; if self.Go.build ~= nil and self.Done.build ~= false then self:anim("build", false); end; if not self.firstRunLvl then self.firstRunLvl = true; FruitUtil.fruitIndexToDesc[self.currentFillType].pricePerLiter = self.pricePerLiter; FruitUtil.fruitIndexToDesc[self.currentFillType].literPerQm = self.literPerQm; end; if self.inLowRange or self.inArmRange then if self.fillLowGo or self.fillArmGo then g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.manureTrigger_refuel).. ": " ..g_i18n:getText("manureTrigger_8")); else g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.manureTrigger_refuel).. ": " ..g_i18n:getText("manureTrigger_7")); end; --if InputBinding.hasEvent(InputBinding.manureTrigger_refuel) then --self.fillLowGo = not self.fillLowGo; --self.fillArmGo = not self.fillArmGo; --end; end; self:farmerInRange(); end; function manureTrigger:manureInLowRange(dt) self.inLowRange = false; local nearestDistance = 4.0; local px, py, pz = getWorldTranslation(self.fillLowNode); for i=1, table.getn(g_currentMission.attachables) do local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].rootNode); local distance = Utils.vector3Length(px-vx, py-vy, pz-vz); if distance < nearestDistance then local attachable = g_currentMission.attachables[i]; self.trailerInRange = g_currentMission.attachables[i]; if attachable.setFillLevel ~= nil and not attachable.allowFillWithArm then for fruitType,v in pairs(attachable.fillTypes) do if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode then if attachable.fillLevel ~= attachable.capacity then self.inLowRange = true; if self.fillLowGo then local deltaLevel = self.fillPerSecond*dt/1000.0; deltaLevel = math.min(deltaLevel, attachable.capacity - attachable.fillLevel); self.fillLevel = self.fillLevel-deltaLevel; self:setFillLevel(self.fillLevel - deltaLevel, self.currentFillType); attachable:setFillLevel(attachable.fillLevel + deltaLevel, self.currentFillType); end; end; end; end; end; nearestDistance = distance; end; end; if not self.inLowRange then self.fillLowGo = false; else self.fillLowGo = true; end; end; function manureTrigger:manureInArmRange(dt) self.inArmRange = false; local nearestDistance = 6.0; local px, py, pz = getWorldTranslation(self.fillArmNode); for i=1, table.getn(g_currentMission.attachables) do if g_currentMission.attachables[i].fillArmNode ~= nil then local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].fillArmNode); local distance = Utils.vector3Length(px-vx, py-vy, pz-vz); if distance < nearestDistance then local attachable = g_currentMission.attachables[i]; if attachable.setFillLevel ~= nil and attachable.allowFillWithArm then for fruitType,v in pairs(attachable.fillTypes) do if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode then if attachable.fillLevel ~= attachable.capacity then self.inArmRange = true; if self.fillArmGo then local deltaLevel = self.fillPerSecond*dt/1000.0; deltaLevel = math.min(deltaLevel, attachable.capacity - attachable.fillLevel); self.fillLevel = self.fillLevel-deltaLevel; self:setFillLevel(self.fillLevel - deltaLevel, self.currentFillType); attachable:setFillLevel(attachable.fillLevel + deltaLevel, self.currentFillType); end; end; end; end; end; nearestDistance = distance; end; end; end; if not self.inArmRange then self.fillArmGo = false; else self.fillArmGo = true; end; end; function manureTrigger:farmerInRange(dt) local nearestDistance = 4.0; local px, py, pz = getWorldTranslation(self.rootNode); local vx, vy, vz = getWorldTranslation(Player.rootNode); local distance = Utils.vector3Length(px-vx, py-vy, pz-vz); if distance < nearestDistance then if self.modus == 0 then -- trigger bauansicht g_currentMission:addHelpButtonText(g_i18n:getText("manureTrigger_1"), InputBinding.LOWER_IMPLEMENT); if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then self.modus = 1; end; elseif self.modus == 1 then -- trigger aufbauen g_currentMission:addHelpButtonText(g_i18n:getText("manureTrigger_2"), InputBinding.IMPLEMENT_EXTRA); if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then self.modus = 2; end; elseif self.modus == 3 then -- trigger einpacken g_currentMission:addHelpButtonText(g_i18n:getText("manureTrigger_5"), InputBinding.IMPLEMENT_EXTRA); if InputBinding.isPressed(InputBinding.IMPLEMENT_EXTRA) then self.modus = 4; end; end; end; end; function manureTrigger:delete() link(self.comp1Node, self.comp1Node); end; function manureTrigger:anim(varName, loopCheck) if self.moveColli[varName] ~= nil then local Collision = self.collisionArm[varName]; setJointFrame(Collision.index, 0, Collision.armAttacher); end; if self.Go[varName] == true and self.Done[varName] ~= false then local charId = getAnimCharacterSet(self.charId[varName]); local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]); assignAnimTrackClip(charId , 0, clipIndex); setAnimTrackLoopState(charId, 0, loopCheck); setAnimTrackSpeedScale(charId, 0, 1); enableAnimTrack(charId, 0); if getAnimTrackTime(charId, 0) >= getAnimClipDuration(charId, clipIndex) and loopCheck == false then disableAnimTrack(charId, 0); self.Done[varName] = false; self.CheckDone[varName] = true; end; elseif self.Go[varName] == false and self.Done[varName] ~= false then local charId = getAnimCharacterSet(self.charId[varName]); local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]); if loopCheck == true then disableAnimTrack(charId, 0); self.Done[varName] = false; end; assignAnimTrackClip(charId , 0, clipIndex); setAnimTrackLoopState(charId, 0, loopCheck); setAnimTrackSpeedScale(charId, 0, -1); enableAnimTrack(charId, 0); if getAnimTrackTime(charId, 0) <= 0 then disableAnimTrack(charId, 0); self.Done[varName] = false; self.CheckDone[varName] = false; end; end; end; function manureTrigger:connectCollisions(varName) local Collision = self.collisionArm[varName]; local constr = JointConstructor:new(); constr:setActors(self.rootNode, Collision.collision); constr:setJointTransforms(Collision.armAttacher, Collision.collisionAttacher); for i=1, 3 do constr:setRotationLimit(i-1, 0, 0, 0); constr:setTranslationLimit(i-1, true, 0, 0); end; Collision.index = constr:finalize(); end; function manureTrigger:mouseEvent(posX, posY, isDown, isUp, button) end; function manureTrigger:keyEvent(unicode, sym, modifier, isDown) end; function manureTrigger:draw() end; function manureTrigger:loadFromAttributesAndNodes(xmlFile, key, resetVehicles) if resetVehicles then self.modus = 0; else self.modus = Utils.getNoNil(getXMLFloat(xmlFile, key.."#modus"), 0); end; return BaseMission.VEHICLE_LOAD_OK; end; function manureTrigger:getSaveAttributesAndNodes(nodeIdent) if self.modus == 4 then self.modus = 0; end; local attributes = 'modus="'..tonumber(self.modus)..'"'; return attributes, nil; end;