home *** CD-ROM | disk | FTP | other *** search
/ Singles (French) / Singles-FrenchVersion-Win95.iso / data1.cab / Statemachine / character.lua < prev    next >
Text File  |  2004-03-05  |  47KB  |  1,317 lines

  1. -- character state machine
  2. -- called by init
  3. -- this: characterGO
  4. function initCharacter()
  5.     -- this function is called when the characters is newly created
  6.     -- set the time the character needs from getting up to getting to work
  7.     this.storeData("workPrepareTime", tonumber(readConfig("Game", "workPrepareTime")));
  8.     -- set the minimum time the character thinks between actions
  9.     this.storeData("minThinkTime", tonumber(readConfig("Game", "minThinkTime")));
  10.     -- set the maximal time the character thinks between actions
  11.     this.storeData("maxThinkTime", tonumber(readConfig("Game", "maxThinkTime")));
  12. end
  13.  
  14.  
  15. beginStateMachine()
  16.     
  17.     onEnter(function(msg)
  18.         -- preload animations
  19.         
  20.         --print("character::onEnter archtype: " .. getArchtypeSuffix(this));
  21.         
  22.         -- walk
  23.         local wso = this.walkSO;
  24.         wso.preloadAnimation(archize(this, "stand1"));
  25.         wso.preloadAnimation(archize(this, "stand2"));
  26.         wso.preloadAnimation(archize(this, "stand3"));
  27.         wso.preloadAnimation(archize(this, "stand4"));
  28.         wso.preloadAnimation(archizeWalk(this, "stand-walkLFF-"));
  29.         wso.preloadAnimation(archizeWalk(this, "walkRFF-walkLFF-"));
  30.         wso.preloadAnimation(archizeWalk(this, "walkLFF-walkRFF-"));
  31.  
  32.         -- mimic
  33.         local mso = this.mimicSO;
  34.         mso.preloadAnimation("mimicEyeBlink");
  35.         mso.preloadAnimation("mimicNeutral1");
  36.         mso.preloadAnimation("mimicNeutral2");
  37.         mso.preloadAnimation("mimicNeutral3");
  38.         mso.preloadAnimation("mimicEyeClose");
  39.         mso.preloadAnimation("mimicSmile1");
  40.         mso.preloadAnimation("mimicSmile2");
  41.         mso.preloadAnimation("mimicSmile3");
  42.         mso.preloadAnimation("mimicSmile4");
  43.         mso.preloadAnimation("mimicSmile5");
  44.         mso.preloadAnimation("mimicAngry1");
  45.         mso.preloadAnimation("mimicSad1");
  46.     end)
  47.     
  48.     onMsg("init", function(msg)
  49.         initCharacter();
  50.     end )
  51.     
  52.     onMsg("buildMenu", function(msg)
  53.         local currentCharacter = getStateObjectFromID(msg.sender);
  54.         print("character buildMenu " .. currentCharacter.getCharacterName().. "->" .. this.getCharacterName());
  55.         -- build the pie menu
  56.         clearPieMenu();
  57.         local button ;
  58.         
  59. --        local bed = this.getObjectWithActivity("sleep");
  60. --        if (bed and bed.hasBehavior("")) then
  61. --            button = addPieMenuButton("pm_getIntimateBed", "getIntimateBed");
  62. --            button.addDescription(ACTIVITY, "getIntimateBed");
  63.             --button.addDescription(DONTQUEUE, "true");
  64. --        end
  65.         
  66.         
  67.         local ibed = getInteractionBed(this, currentCharacter);
  68.         if (ibed) then
  69.         
  70. --            button = addPieMenuButton("pm_kissBed", "kissBed");
  71. --            button.addDescription(ACTIVITY, "kissBed");
  72.         
  73.             button = addPieMenuButton("pm_pettingBed", "pettingBed");
  74.             button.addDescription(ACTIVITY, "pettingBed");
  75.         
  76.             local bothMale = ( 
  77.                 (currentCharacter.getGameObjectServer().getCharacter(ELAINE).isTransgender()) and
  78.                 (not currentCharacter.getGameObjectServer().getCharacter(MIKE).isTransgender())
  79.                 );
  80.                 
  81.             local bothHomo = ( 
  82.                 (currentCharacter.getGameObjectServer().getCharacter(ELAINE).isTransgender()) and
  83.                 (currentCharacter.getGameObjectServer().getCharacter(MIKE).isTransgender())
  84.                 );
  85.                 
  86.             
  87.             if (not bothMale) and (not bothHomo) then
  88.                 button = addPieMenuButton("pm_sexBed", "sexBed");
  89.                 button.addDescription(ACTIVITY, "sexBed");
  90.             end
  91.         else
  92.         
  93.         end
  94.                 
  95.         
  96.         if ((not bed) and (not ibed) and (not (this.isSwimming()))) then        
  97.         --if ((not bed) and (not ibed)) then
  98.                 
  99.                 
  100.             local romanceButton = addPieMenuButton("pm_romance", "");
  101.             romanceButton.addIcon("guiIconRelationshipRomantic");
  102.             
  103.                 button = romanceButton.addPieMenuButton("pm_talkRelation", "talk", "Relation");
  104.                 button.addDescription(ACTIVITY, "talkRelation");
  105.                 
  106.                 button = romanceButton.addPieMenuButton("pm_talkCompliment", "talk", "Compliment");
  107.                 button.addDescription(ACTIVITY, "talkCompliment");
  108.                 
  109.                 button = romanceButton.addPieMenuButton("pm_holdNice", "holdNice");
  110.                 button.addDescription(ACTIVITY, "holdNice");
  111.                 
  112.                 button = romanceButton.addPieMenuButton("pm_kissFriendly", "kiss", "Friendly");
  113.                 button.addDescription(ACTIVITY, "kissFriendly");
  114.  
  115.                 button = romanceButton.addPieMenuButton("pm_kissIntimate", "kiss", "Intimate");
  116.                 button.addDescription(ACTIVITY, "kissIntimate");
  117.                 
  118.                 button = romanceButton.addPieMenuButton("pm_talkILoveYou", "talk", "ILoveYou");
  119.                 button.addDescription(ACTIVITY, "talkILoveYou");
  120.  
  121.                 if (canMarry(currentCharacter, this) and storyActive(this.getGameObjectServer())) then
  122.                     button = romanceButton.addPieMenuButton("pm_talkMarryMe", "talkMarryMe", "");
  123.                     button.addIcon("guiIconRelationErotic");
  124.                     button.addIcon("guiIconRelationFriendship");
  125.                     button.addDescription(ACTIVITY, "talkILoveYou");
  126.                 end
  127.  
  128.  
  129.  
  130.             local eroticButton = addPieMenuButton("pm_erotic", "");
  131.             eroticButton.addIcon("guiIconLibido");
  132.         
  133.                 button = eroticButton.addPieMenuButton("pm_talkFlirt", "talk", "Flirt");
  134.                 button.addDescription(ACTIVITY, "talkFlirt");
  135.                 
  136.                 button = eroticButton.addPieMenuButton("pm_kissSexy", "kissSexy", "Sexy"); -- special kiss
  137.                 button.addDescription(ACTIVITY, "kissSexy");
  138.                 
  139.                 if (currentCharacter.isMale()) then
  140.                     button = eroticButton.addPieMenuButton("pm_holdBehind", "holdBehind");
  141.                     button.addDescription(ACTIVITY, "holdBehind");
  142.                 end;
  143.                 
  144.                 button = eroticButton.addPieMenuButton("pm_getIntimateBed", "getIntimateBed");
  145.                 button.addDescription(ACTIVITY, "getIntimateBed");
  146.                 
  147.                 button = eroticButton.addPieMenuButton("pm_getIntimateSofa", "getIntimateSofa");
  148.                 button.addDescription(ACTIVITY, "kissIntimate");
  149.                 
  150. --                local sofa = this.getObjectWithActivity("sit");
  151. --                if (sofa and sofa.hasBehavior("sofa")) then
  152. --                    button = eroticButton.addPieMenuButton("pm_getIntimateSofa", "getIntimateSofa");
  153. --                    button.addDescription(ACTIVITY, "kissIntimate");
  154. --                end
  155.                 
  156.                 
  157.             local otherButton = addPieMenuButton("pm_other", "");
  158.             otherButton.addIcon("guiIconSpass");
  159.             
  160.                 button = otherButton.addPieMenuButton("pm_talkJoke", "talk", "Joke");
  161.                 button.addDescription(ACTIVITY, "talkJoke");
  162.                 
  163.                 button = otherButton.addPieMenuButton("pm_talkTease", "talk", "Tease");
  164.                 button.addDescription(ACTIVITY, "talkTease");
  165.  
  166.  
  167.             local friendshipButton = addPieMenuButton("pm_friendship", "");
  168.             friendshipButton.addIcon("guiIconRelationshipFriendship");
  169.  
  170.                 button = friendshipButton.addPieMenuButton("pm_talkCasual", "talk", "Casual");
  171.                 button.addDescription(ACTIVITY, "talkCasual");
  172.                 
  173.                 button = friendshipButton.addPieMenuButton("pm_talkGossip", "talk", "Gossip");
  174.                 button.addDescription(ACTIVITY, "talkGossip");
  175.  
  176.                 button = friendshipButton.addPieMenuButton("pm_talkComfort", "talk", "Comfort");
  177.                 button.addDescription(ACTIVITY, "talkComfort");
  178.  
  179.                 button = friendshipButton.addPieMenuButton("pm_talkHobby", "talk", "Hobby");
  180.                 button.addDescription(ACTIVITY, "talkHobby");
  181.                 
  182.                 
  183.             
  184.             --button = addPieMenuButton("pm_talkCutscene", "talkCutscene");
  185.         
  186.         end;
  187.         
  188.                 
  189.         local hasGift = holdsObject(currentCharacter, "gift");
  190.         --print("hasGift: " , hasGift);
  191.         if (hasGift) then
  192.             button = addPieMenuButton("pm_giveGift", "giveGift");
  193.             button.addDescription(ACTIVITY, "giveGift");
  194.         end
  195.         
  196.     end )
  197.     
  198.  
  199.  
  200.  
  201.     -- generic talk
  202.     onMsg("talk", function(msg)
  203.         
  204.         -- get the game object server
  205.         local gameObjectServer = getGameObjectServer();
  206.         -- get character who initiated this action
  207.         local character = getStateObjectFromID(msg.sender);
  208.         -- get the suffix
  209.         local talkType = msg.data;
  210.         
  211.         print(">>>>> onMsg talk" .. msg.data .." character " .. character.getCharacterName() .. " -> " .. getCharacterName());
  212.         
  213.         --if (instantAbortIfNotIdle(character, this)) then return end;
  214.         
  215.         if instantAbortIfUnhappy(character, "talk" .. talkType, this) then return end;        
  216.         
  217.         
  218.         -- check if the activity is possible
  219. --        if (activityPossible(character, msg.name, this) and isIdle(this)) then
  220.         local possible, result, activity = activityPossible(character, "talk" .. talkType, this);
  221.         
  222.         -- don't care if timeslot is not fulfilled
  223.         if (possible or enumCompare(result, TIMESLOT)) then
  224.         
  225.             -- walk to the interaction point
  226.             local interactionPoint = findInteractionPoint("talk", character);
  227.             if (interactionPoint) then
  228.                 -- get the walk state objects
  229.                 local wso = character.walkSO;
  230.                 local thisWso = this.walkSO;
  231.                 -- create state machine contexts
  232.                 local wsoContext =  StateMachineContext();
  233.                 local thisWsoContext =  StateMachineContext();
  234.                 -- store the partners
  235.                 wsoContext.storeStateObject("partner", thisWso);
  236.                 wsoContext.storeData("activePart", true);
  237.                 wsoContext.storeData("talkType", talkType);
  238.                 thisWsoContext.storeStateObject("partner", wso);
  239.                 thisWsoContext.storeData("activePart", false);
  240.                 thisWsoContext.storeData("talkType", talkType);
  241.                 thisWsoContext.storeData("waitLong", isIdle(this));
  242.                 -- start action for other character
  243.                 if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  244.                     -- wso.queueMessage("waitForChar", this, "talk", wsoContext);
  245.                     wso.queueStateMachine("interaction.talk", this, wsoContext);
  246.                     
  247.                     -- queue walk and state change msg for this(passive) character
  248.                     local passiveMsg = QueuedMessage();
  249.                     -- passiveMsg.set("waitForChar", this.getUniqueID(), "talk", thisWsoContext);
  250.                     passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.talk", thisWsoContext);
  251.                     
  252.                     print("-----------------------> passive character pushWalkActionPoint");
  253.                     local walkQueueEntry = this.pushWalkActionPoint("pm_talk"..talkType, interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);
  254.  
  255.                     
  256.                     -- start action for this character
  257. --                    if (thisWso.walkToActionPoint(interactionPoint.getPassiveActionPoint())) then
  258. --                        thisWso.queueMessage("waitForChar", this, "talk", thisWsoContext);
  259. --                    else
  260. --                        print("no path found");
  261. --                        instantAbort(this, EMOTICON_NOPATH, "emoThink")
  262. --                    end
  263.  
  264.                 else
  265.                     print("no path found");
  266.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  267.                 end
  268.             else
  269.                 print("no interaction point found");
  270.                 instantAbort(character, EMOTICON_NOPATH, "emoThink")
  271.             end
  272.         else
  273.             -- activity not possible
  274.             print(msg.name .. " not possible");
  275.             --sendMsg("sad", character.mimicSO);
  276.             -- instantAbort(character, EMOTICON_SHY, "emoRefuseChar", this)
  277.             local emoticon;
  278.             if (enumCompare(result, NO_CONDITION)) then
  279.                 emoticon = conditionToEmoticon(activity.getUnfulfilledCondition());
  280.             else
  281.                 emoticon = EMOTICON_SAD
  282.             end
  283.             instantAbort(character, emoticon, "emoRefuseChar", this)
  284.             
  285.             -- show emoticon if activity was not possible on partner
  286.             if (enumCompare(result, NO_PARTNERCONDITION) or enumCompare(result, NO_PARTNERSATISFACTION)) then
  287.                 local emoticon;
  288.                 local unfulfilledPartnerCondition = activity.getUnfulfilledPartnerCondition();
  289.                 if (not enumCompare(unfulfilledPartnerCondition, NEED_NONE)) then
  290.                     emoticon = conditionToEmoticon(unfulfilledPartnerCondition);
  291.                 else
  292.                     emoticon = EMOTICON_SAD
  293.                 end
  294.                 
  295.                 this.setEmoticon(emoticon, EMOTICON_DELAY);
  296.             end
  297.             
  298.         end
  299.     end )
  300.         
  301.         
  302.     -- cutscene talk
  303.     onMsg("talkMarryMe", function(msg)
  304.         
  305.         -- get character who initiated this action
  306.         local character = getStateObjectFromID(msg.sender);
  307.         
  308.         print(">>+>> onMsg talkMarryMe character " .. character.getCharacterName() .. " -> " .. getCharacterName());
  309.         
  310.         -- marry here
  311.         instantAbort(character);
  312.         
  313.         
  314.         
  315.     end )
  316.         
  317.         
  318.     -- cutscene talk
  319.     onMsg("talkCutscene", function(msg)
  320.  
  321.         -- get the game object server
  322.         local gameObjectServer = getGameObjectServer();
  323.         -- get character who initiated this action
  324.         local character = getStateObjectFromID(msg.sender);
  325.         
  326.         --if (instantAbortIfNotIdle(character, this)) then return end;
  327.         
  328.         print(">>>>> onMsg talkCutscene character " .. character.getCharacterName() .. " -> " .. getCharacterName() .. " topic " .. msg.data);
  329.         
  330.         --if (character.isSwimming() or this.isSwimming()) then return end;
  331.  
  332. --        if (character.isSwimming() or this.isSwimming()) then 
  333. --            print("no path found");
  334. --            instantAbort(character, EMOTICON_NOPATH, "emoThink")
  335. --            return
  336. --        end;
  337.  
  338.         
  339.         -- walk to the interaction point
  340.  
  341.         -- get the walk state objects
  342.         local wso = character.walkSO;
  343.         local thisWso = this.walkSO;
  344.         -- create state machine contexts
  345.         local wsoContext =  StateMachineContext();
  346.         local thisWsoContext =  StateMachineContext();
  347.         -- store the partners
  348.         wsoContext.storeStateObject("partner", thisWso);
  349.         wsoContext.storeData("activePart", true);
  350.         wsoContext.storeData("topic", msg.data);
  351.         thisWsoContext.storeStateObject("partner", wso);
  352.         thisWsoContext.storeData("activePart", false);
  353.         thisWsoContext.storeData("waitLong", isIdle(this));
  354.         thisWsoContext.storeData("topic", msg.data);
  355.  
  356.         local interactionPoint = findInteractionPoint("talk", character);
  357.         if (interactionPoint) then
  358.  
  359.             -- start action for other character
  360.             if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  361.                 -- wso.queueMessage("waitForChar", this, "talkCutscene", wsoContext);
  362.                 wso.queueStateMachine("interaction.talkCutscene", this, wsoContext);
  363.  
  364.                 -- queue walk and state change msg for this(passive) character
  365.                 local passiveMsg = QueuedMessage();
  366.                 -- passiveMsg.set("waitForChar", this.getUniqueID(), "talkCutscene", thisWsoContext);
  367.                 passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.talkCutscene", thisWsoContext);
  368.                 print("-----------------------> passive character pushWalkActionPoint");
  369.                 local walkQueueEntry = this.pushWalkActionPoint("pm_talkCutscene", interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);
  370.                 
  371.                 
  372.                 
  373.             else
  374.                 print("talkCutscene - no path found");
  375.                 --instantAbort(character, EMOTICON_NOPATH, "emoThink")
  376.  
  377. --                wso.queueStateMachine("interaction.talkCutscene", this, wsoContext);
  378. --                thisWso.queueStateMachine("interaction.talkCutscene", this, thisWsoContext);
  379.  
  380.                 character.sendDelayedMsg("talking", getGameObjectServer().mission, 500, msg.data);
  381.     
  382.             end
  383.         else
  384.             print("talkCutscene - no interaction point found");
  385.             --instantAbort(character, EMOTICON_CANNOT, "emoThink")
  386.  
  387. --            wso.queueStateMachine("interaction.talkCutscene", this, wsoContext);
  388. --            thisWso.queueStateMachine("interaction.talkCutscene", this, thisWsoContext);
  389.  
  390.             character.sendDelayedMsg("talking", getGameObjectServer().mission, 500, msg.data);
  391.  
  392.         end
  393.  
  394.     end )
  395.         
  396.         
  397.         
  398.         
  399.         
  400.         
  401.         
  402.         
  403.         
  404.         
  405.         
  406.         
  407.         
  408.         
  409.         
  410.     -- generic kiss
  411.     onMsg("kiss", function(msg)
  412.         
  413.         -- get the game object server
  414.         local gameObjectServer = getGameObjectServer();
  415.         -- get character who initiated this action
  416.         local character = getStateObjectFromID(msg.sender);
  417.         -- get the suffix
  418.         local kissType = msg.data;
  419.         
  420.         --if (instantAbortIfNotIdle(character, this)) then return end;
  421.         
  422.         if instantAbortIfUnhappy(character, "kiss" .. kissType, this) then return end;        
  423.         
  424.         
  425. --        local actionPointName = "kiss";
  426. --        if (kissType == "Sexy") actionPointName = "talk"; end; -- hack, bad animation
  427.         
  428.         -- check if the activity is possible
  429.         --if (activityPossible(character, "kiss" .. kissType, this) and isIdle(this)) then
  430.         
  431.         local possible, result, activity = activityPossible(character, "kiss" .. kissType, this)
  432.  
  433.         -- don't care if timeslot is not fulfilled
  434.         if (possible or enumCompare(result, TIMESLOT)) then
  435.         
  436.             -- walk to the interaction point
  437.             local interactionPoint = findInteractionPoint("kiss", character);
  438.             if (interactionPoint) then
  439.                 -- get the walk state objects
  440.                 local wso = character.walkSO;
  441.                 local thisWso = this.walkSO;
  442.                 -- create state machine contexts
  443.                 local wsoContext =  StateMachineContext();
  444.                 local thisWsoContext = StateMachineContext();
  445.                 -- store the partners
  446.                 wsoContext.storeStateObject("partner", thisWso);
  447.                 wsoContext.storeData("activePart", true);
  448.                 wsoContext.storeData("kissType", kissType);
  449.                 thisWsoContext.storeStateObject("partner", wso);
  450.                 thisWsoContext.storeData("activePart", false);
  451.                 thisWsoContext.storeData("kissType", kissType);
  452.                 thisWsoContext.storeData("waitLong", isIdle(this));
  453.                 -- start action for other character
  454.                 if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  455.                     -- wso.queueMessage("waitForChar", this, "kiss", wsoContext);
  456.                     wso.queueStateMachine("interaction.kiss", this, wsoContext);
  457.  
  458.                     -- queue walk and state change msg for this(passive) character
  459.                     local passiveMsg = QueuedMessage();
  460.                     -- passiveMsg.set("waitForChar", this.getUniqueID(), "kiss", thisWsoContext);
  461.                     passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.kiss", thisWsoContext);
  462.  
  463.                     print("-----------------------> passive character pushWalkActionPoint");
  464.                     local walkQueueEntry = this.pushWalkActionPoint("pm_kiss"..kissType , interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);
  465.                 else
  466.                     print("no path found");
  467.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  468.                 end
  469.             else
  470.                 print("no interaction point found");
  471.                 instantAbort(character, EMOTICON_CANNOT, "emoThink")
  472.             end
  473.         else
  474.             -- activity not possible
  475.             print(msg.name .. " not possible");
  476.             --sendMsg("sad", character.mimicSO);
  477.             --instantAbort(character, EMOTICON_SHY, "emoRefuseChar", this)
  478.             
  479.             local emoticon;
  480.             if (enumCompare(result, NO_CONDITION)) then
  481.                 emoticon = conditionToEmoticon(activity.getUnfulfilledCondition());
  482.             else
  483.                 emoticon = EMOTICON_SAD
  484.             end
  485.             instantAbort(character, emoticon, "emoRefuseChar", this)
  486.             
  487.             -- show emoticon if activity was not possible on partner
  488.             if (enumCompare(result, NO_PARTNERCONDITION) or enumCompare(result, NO_PARTNERSATISFACTION)) then
  489.                 local emoticon;
  490.                 local unfulfilledPartnerCondition = activity.getUnfulfilledPartnerCondition();
  491.                 if (not enumCompare(unfulfilledPartnerCondition, NEED_NONE)) then
  492.                     emoticon = conditionToEmoticon(unfulfilledPartnerCondition);
  493.                 else
  494.                     emoticon = EMOTICON_SAD
  495.                 end
  496.                 
  497.                 this.setEmoticon(emoticon, EMOTICON_DELAY);
  498.             end
  499.         end
  500.     end )
  501.  
  502.  
  503.  
  504.  
  505.  
  506.     -- kissSexy kiss special: has loop
  507.     onMsg("kissSexy", function(msg)
  508.         
  509.         -- get the game object server
  510.         local gameObjectServer = getGameObjectServer();
  511.         -- get character who initiated this action
  512.         local character = getStateObjectFromID(msg.sender);
  513.         -- get the suffix
  514.         local kissType = msg.data;
  515.         
  516.         --if (instantAbortIfNotIdle(character, this)) then return end;
  517.         
  518.         if instantAbortIfUnhappy(character, msg.name, this) then return end;        
  519.  
  520.                 
  521.         -- check if the activity is possible
  522.         --if (activityPossible(character, msg.name, this) and isIdle(this)) then
  523.         
  524.         local possible, result, activity = activityPossible(character, msg.name, this)
  525.  
  526.         -- don't care if timeslot is not fulfilled
  527.         if (possible or enumCompare(result, TIMESLOT)) then
  528.         
  529.             -- walk to the interaction point
  530.             local interactionPoint = findInteractionPoint("talk", character);
  531.             if (interactionPoint) then
  532.                 -- get the walk state objects
  533.                 local wso = character.walkSO;
  534.                 local thisWso = this.walkSO;
  535.                 -- create state machine contexts
  536.                 local wsoContext =  StateMachineContext();
  537.                 local thisWsoContext = StateMachineContext();
  538.                 -- store the partners
  539.                 wsoContext.storeStateObject("partner", thisWso);
  540.                 wsoContext.storeData("activePart", true);
  541.                 wsoContext.storeData("kissType", kissType);
  542.                 thisWsoContext.storeStateObject("partner", wso);
  543.                 thisWsoContext.storeData("activePart", false);
  544.                 thisWsoContext.storeData("kissType", kissType);
  545.                 thisWsoContext.storeData("waitLong", isIdle(this));
  546.                 -- start action for other character
  547.                 if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  548.                     -- wso.queueMessage("waitForChar", this, "kissSexy", wsoContext);
  549.                     wso.queueStateMachine("interaction.kissSexy", this, wsoContext);
  550.  
  551.                     -- queue walk and state change msg for this(passive) character
  552.                     local passiveMsg = QueuedMessage();
  553.                     -- passiveMsg.set("waitForChar", this.getUniqueID(), "kissSexy", thisWsoContext);
  554.                     passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.kissSexy", thisWsoContext);
  555.                     
  556.                     print("-----------------------> passive character pushWalkActionPoint");
  557.                     local walkQueueEntry = this.pushWalkActionPoint("pm_kissSexy", interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);
  558.  
  559.                     
  560. --                    -- start action for this character
  561. --                    if (thisWso.walkToActionPoint(interactionPoint.getPassiveActionPoint())) then
  562. --                        thisWso.queueMessage("waitForChar", this, "kissSexy", thisWsoContext);
  563. --                    else
  564. --                        print("no path found");
  565. --                        instantAbort(this, EMOTICON_NOPATH, "emoThink")
  566. --                    end
  567.                 else
  568.                     print("no path found");
  569.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  570.                 end
  571.             else
  572.                 print("no interaction point found");
  573.                 instantAbort(character, EMOTICON_CANNOT, "emoThink")
  574.             end
  575.         else
  576.             -- activity not possible
  577.             print(msg.name .. " not possible");
  578.             --sendMsg("sad", character.mimicSO);
  579.             --instantAbort(character, EMOTICON_SHY, "emoRefuseChar", this)
  580.             
  581.             local emoticon;
  582.             if (enumCompare(result, NO_CONDITION)) then
  583.                 emoticon = conditionToEmoticon(activity.getUnfulfilledCondition());
  584.             else
  585.                 emoticon = EMOTICON_SAD
  586.             end
  587.             instantAbort(character, emoticon, "emoRefuseChar", this)
  588.             
  589.             -- show emoticon if activity was not possible on partner
  590.             if (enumCompare(result, NO_PARTNERCONDITION) or enumCompare(result, NO_PARTNERSATISFACTION)) then
  591.                 local emoticon;
  592.                 local unfulfilledPartnerCondition = activity.getUnfulfilledPartnerCondition();
  593.                 if (not enumCompare(unfulfilledPartnerCondition, NEED_NONE)) then
  594.                     emoticon = conditionToEmoticon(unfulfilledPartnerCondition);
  595.                 else
  596.                     emoticon = EMOTICON_SAD
  597.                 end
  598.                 
  599.                 this.setEmoticon(emoticon, EMOTICON_DELAY);
  600.             end
  601.         end
  602.     end )
  603.  
  604.  
  605.  
  606.  
  607.  
  608.     
  609.     
  610.     
  611.     -- getIntimateSofa
  612.     onMsg("getIntimateSofa", function(msg)
  613.         
  614.         -- get character who initiated this action
  615.         local character = getStateObjectFromID(msg.sender);
  616.         
  617.         
  618.         -- get the sofa on wcjich this character is sitting
  619.         local sofa = this.getObjectWithActivity("sit");
  620.         if ((not sofa) or (not sofa.hasBehavior("sofa"))) then
  621.         
  622.             print("   getIntimate: no not on sofa");
  623.             
  624.             local freeSofa, actionPoint1, actionPoint2 = findSofaForInteraction(this, character);
  625.             if (freeSofa) then
  626.             
  627.                 local possible, mirrorAnims = getSofaInteractionInfo(this, character, actionPoint1.getName(), actionPoint2.getName());
  628.                 -- don't care if timeslot is not fulfilled
  629.                 if (possible) then
  630.             
  631.                     -- get the walk state objects
  632.                     local wso = character.walkSO;
  633.                     local thisWso = this.walkSO;
  634.                     
  635.                     if (wso.walkToActionPoint(actionPoint2)) then
  636.                                         
  637.                             print("free sofa found");
  638.                         
  639.                             -- create state machine contexts
  640.                             local wsoContext =  StateMachineContext();
  641.                             local thisWsoContext =  StateMachineContext();
  642.                                         
  643.                             wsoContext.storeData("actionPointName", actionPoint2.getName());
  644.                             wsoContext.storeStateObject("partner", thisWso);
  645.                             wsoContext.storeData("sitState", "waitIntimate");
  646.                             wsoContext.storeStateObject("sofa", freeSofa);
  647.                             wsoContext.storeData("mirrorAnims", mirrorAnims);
  648.                             wsoContext.storeData("activePart", true);
  649.                                         
  650.                             thisWsoContext.storeData("actionPointName", actionPoint1.getName());
  651.                             thisWsoContext.storeStateObject("partner", wso);
  652.                             thisWsoContext.storeData("sitState", "waitIntimate");
  653.                             thisWsoContext.storeStateObject("sofa", freeSofa);
  654.                             thisWsoContext.storeData("mirrorAnims", mirrorAnims);
  655.                             thisWsoContext.storeData("activePart", false);                        
  656.                             
  657.                             wso.queueStateMachine("sofaChar.sitDown", this, wsoContext);
  658.                             
  659.                             -- queue walk and state change msg for this(passive) character
  660.                             local passiveMsg = QueuedMessage();
  661.                             passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "sofaChar.sitDown", thisWsoContext);
  662.                             local walkQueueEntry = this.pushWalkActionPoint("pm_getIntimateSofa", actionPoint1, false, passiveMsg, true);
  663.     
  664.                     else
  665.                         print("getIntimateSofa: no path found");
  666.                         instantAbort(character, EMOTICON_NOPATH, "emoThink")
  667.                     end
  668.                 
  669.                 else
  670.                     print("getIntimateSofa: not possible on action points: " .. actionPoint1.getName() .. " , " .. actionPoint2.getName());
  671.                     instantAbort(character, EMOTICON_NOSOFA, "emoThink")
  672.                 end
  673.             else
  674.                 print("getIntimateSofa: no action point found of layDown1, layDown2");
  675.                 instantAbort(character, EMOTICON_NOSOFA, "emoThink")
  676.             end
  677.  
  678.  
  679.         else
  680.         
  681.         
  682.             -- get the walk state objects
  683.             local wso = character.walkSO;
  684.             local thisWso = this.walkSO;
  685.             
  686.             local thisActionPointName = thisWso.retrieveData("actionPointName");
  687.             if (not thisActionPointName) then
  688.                 print("getIntimateSofa: thisActionPointName == nil");
  689.                 instantAbort(character, EMOTICON_CANNOT, "emoThink");
  690.                 return
  691.             end
  692.             
  693.             local actionPointName = nil;
  694.             local mirrorAnims = false;
  695.             
  696.             
  697.             
  698.     
  699.             local thisMale = this.isMale();
  700.             
  701.             print("--------------getIntimateSofa passive character on actionpoint:" .. thisActionPointName .. " male:" .. tostring(thisMale));
  702.             if (thisActionPointName == "sit1") then 
  703.                 if (thisMale) then
  704.                     actionPointName = "sit2";
  705.                 else
  706.                     actionPointName = "sit2";
  707.                     mirrorAnims = true;
  708.                 end
  709.             elseif (thisActionPointName == "sit2") then
  710.                 if (thisMale) then
  711.                     actionPointName = "sit3";
  712.                 else
  713.                     actionPointName = "sit1";
  714.                 end
  715.             elseif (thisActionPointName == "sit3") then
  716.                 if (thisMale) then
  717.                     actionPointName = "sit2";
  718.                     mirrorAnims = true;
  719.                 else
  720.                     actionPointName = "sit2";
  721.                 end
  722.             else
  723.                 print("getIntimateSofa passive character on unknown actionpoint:" .. thisActionPointName)
  724.                 instantAbort(character, EMOTICON_CANNOT, "emoThink");
  725.             end
  726.             
  727.             print("--------------getIntimateSofa active character to actionpoint:" .. actionPointName .. " mirrorAnims:" .. tostring(mirrorAnims));
  728.             local actionPoint = character.getClosestFreeActionPoint(character, sofa, {actionPointName});
  729.             print("--------------getIntimateSofa getClosestFreeActionPoint returned actionpoint:" .. actionPoint.getName());
  730.     
  731.             if (actionPoint) then
  732.             
  733.                 -- create state machine contexts
  734.                 local wsoContext =  StateMachineContext();
  735.                 local thisWsoContext =  StateMachineContext();
  736.                             
  737.                                     
  738.                 if (wso.walkToActionPoint(actionPoint)) then
  739.                 
  740.                     wsoContext.storeData("actionPointName", actionPoint.getName());
  741.                     
  742.                     wsoContext.storeStateObject("partner", thisWso);
  743.                     wsoContext.storeStateObject("sofa", sofa);
  744.                     wsoContext.storeData("sitState", "waitIntimate");
  745.                     wsoContext.storeData("activePart", true);
  746.                     wsoContext.storeData("mirrorAnims", mirrorAnims);
  747.                     
  748.                     thisWso.storeStateObject("partner", wso);
  749.                     thisWso.storeStateObject("sofa", sofa);
  750.                     thisWso.storeData("activePart", false);
  751.                     thisWso.storeData("mirrorAnims", mirrorAnims);
  752.                 
  753.                 
  754.                     print("getIntimateSofa sendMsg waitIntimate & queueStateMachine sofaChar.sitDownToGetIntimate");
  755.                     --wso.queueStateMachine("sofaChar.sitDownToGetIntimate", this, wsoContext);
  756.                     wso.queueStateMachine("sofaChar.sitDown", sofa, wsoContext);
  757.                     sendMsg("waitIntimate", thisWso);
  758.                     
  759.                 else
  760.                     print("no path found");
  761.                     instantAbort(character, EMOTICON_NOPATH, "emoThink");
  762.                     return
  763.                 end
  764.                 
  765.             else
  766.                 print("mike.lua::getIntimateSofa: no action point found " .. actionPointName);
  767.                 instantAbort(character, EMOTICON_CANNOT, "emoThink");
  768.             end
  769.             
  770.         end
  771.         
  772.     end )
  773.     
  774.     
  775.     
  776.     -- getIntimateSofaShortcut
  777.     onMsg("getIntimateSofaShortcut", function(msg)
  778.     
  779.         print("onMsg getIntimateSofaShortcut");
  780.         
  781.         -- get character who initiated this action
  782.         local character = getStateObjectFromID(msg.sender);
  783.                     
  784.         -- get the walk state objects
  785.         local wso = character.walkSO;
  786.         local thisWso = this.walkSO;
  787.         
  788.         local possible, mirrorAnims = getSofaIteractionInfo(character, this);
  789.                 
  790.         wso.storeStateObject("partner", thisWso);
  791.         wso.storeData("activePart", true);
  792.         wso.storeData("mirrorAnims", mirrorAnims);
  793.         
  794.         thisWso.storeStateObject("partner", wso);
  795.         thisWso.storeData("activePart", false);
  796.         thisWso.storeData("mirrorAnims", mirrorAnims);
  797.         
  798.         --thisWso.setState("waitIntimate");
  799.         sendMsg("waitIntimate", thisWso);
  800.             
  801.     end )    
  802.     
  803.     
  804.     
  805.     
  806.     -- getIntimate
  807.     onMsg("getIntimateBed", function(msg)
  808.         -- get character who initiated this action
  809.         local character = getStateObjectFromID(msg.sender);
  810.         -- get the bed on wcjich this character is laying
  811.         local bed = this.getObjectWithActivity("sleep");
  812.         
  813.         print("onMsg getIntimate: no partner in bed");
  814.         
  815.         if instantAbortIfUnhappy(character, "getIntimateBed", this) then return end;        
  816.         
  817.         
  818.         if (not bed) then
  819.             print("   getIntimate: no partner in bed");
  820.             
  821.             --if (instantAbortIfNotIdle(character, this)) then return end;
  822.             
  823.             local freeBed, actionPoint1, actionPoint2 = findBedForInteraction(this, character);
  824.             if (freeBed) then
  825.             -- get the walk state object
  826.             
  827.                 -- get the walk state objects
  828.                 local wso = character.walkSO;
  829.                 local thisWso = this.walkSO;
  830.                 
  831.                 if (wso.walkToActionPoint(actionPoint2)) then
  832.                 
  833. --                    if (thisWso.walkToActionPoint(actionPoint1)) then
  834.                     
  835.                         print("free double bed found");
  836.                     
  837.                         -- create state machine contexts
  838.                         local wsoContext =  StateMachineContext();
  839.                         local thisWsoContext =  StateMachineContext();
  840.                                     
  841.                         wsoContext.storeData("actionPointName", actionPoint2.getName());
  842.                         wsoContext.storeStateObject("partner", thisWso);
  843.                         wsoContext.storeStateObject("bed", freeBed);
  844.                         wsoContext.storeData("activePart", true);
  845.                                     
  846.                         thisWsoContext.storeData("actionPointName", actionPoint1.getName());
  847.                         thisWsoContext.storeStateObject("partner", wso);
  848.                         thisWsoContext.storeStateObject("bed", freeBed);
  849.                         thisWsoContext.storeData("activePart", false);                        
  850.                         
  851.                         --thisWso.queueStateMachine("doublebedChar.layDownToGetIntimate", this, thisWsoContext);
  852.                         wso.queueStateMachine("doublebedChar.layDownToGetIntimate", this, wsoContext);
  853.                         
  854.                         -- queue walk and state change msg for this(passive) character
  855.                         local passiveMsg = QueuedMessage();
  856.                         --passiveMsg.set("enterStateMachine", this.getUniqueID(), "doublebedChar.layDownToGetIntimate", thisWsoContext);
  857.                         passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "doublebedChar.layDownToGetIntimate", thisWsoContext);
  858.                         
  859.                         local walkQueueEntry = this.pushWalkActionPoint("pm_getIntimateBed", actionPoint1, false, passiveMsg, true);
  860.  
  861.                         
  862.                         --this.pushQueueEntry("pm_getIntimateBed");
  863.                         --setTopQueueEntry(this, "pm_getIntimateBed");
  864. --                    else
  865. --                        print("no path found");
  866. --                        instantAbort(this, EMOTICON_NOPATH, "emoThink")
  867. --                    end
  868.                 else
  869.                     print("no path found");
  870.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  871.                 end
  872.             else
  873.                 print("getIntimate: no action point found of layDown1, layDown2");
  874.                 instantAbort(character, EMOTICON_NODOUBLEBED, "emoThink")
  875.             end
  876.             
  877.             
  878.         else
  879.         
  880.             local actionPoint = character.getClosestFreeActionPoint(character, bed, {"layDown1", "layDown2"});
  881.             if (actionPoint) then
  882.             -- get the walk state object
  883.             
  884.                 -- get the walk state objects
  885.                 local wso = character.walkSO;
  886.                 local thisWso = this.walkSO;
  887.                 -- create state machine contexts
  888.                 local wsoContext =  StateMachineContext();
  889.                 local thisWsoContext =  StateMachineContext();
  890.                             
  891.                 wsoContext.storeData("actionPointName", actionPoint.getName());
  892.                 
  893.                 wsoContext.storeStateObject("partner", thisWso);
  894.                 wsoContext.storeStateObject("bed", bed);
  895.                 wsoContext.storeData("activePart", true);
  896.                             
  897.                 thisWso.storeStateObject("partner", wso);
  898.                 thisWso.storeStateObject("bed", bed);
  899.                 thisWso.storeData("activePart", false);
  900.                 
  901.                 if (wso.walkToActionPoint(actionPoint)) then
  902.                     wso.queueStateMachine("doublebedChar.layDownToGetIntimate", this, wsoContext);
  903.                 else
  904.                     print("no path found");
  905.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  906.                 end
  907.                 
  908.                 thisWso.setState("waitIntimate");
  909.             else
  910.                 print("getIntimate: no action point found of layDown1, layDown2");
  911.                 instantAbort(character, EMOTICON_CANNOT, "emoThink")
  912.             end
  913.         
  914.         
  915.         end
  916.                 
  917.     end )
  918.     
  919.     
  920.     
  921.     
  922.     
  923.     -- getIntimateBedShortcut
  924.     onMsg("getIntimateBedShortcut", function(msg)
  925.         print("onMsg getIntimateBedShortcut");
  926.  
  927.         -- get character who initiated this action
  928.         local character = getStateObjectFromID(msg.sender);
  929.         -- get the bed on wcjich this character is laying
  930.         local bed = this.getObjectWithActivity("lie");
  931.         
  932.                 
  933.         -- get the walk state objects
  934.         local wso = character.walkSO;
  935.         local thisWso = this.walkSO;
  936.                     
  937.         
  938.         wso.storeStateObject("partner", thisWso);
  939.         wso.storeStateObject("bed", bed);
  940.         wso.storeData("activePart", true);
  941.         
  942.         
  943.         thisWso.storeStateObject("partner", wso);
  944.         thisWso.storeStateObject("bed", bed);
  945.         thisWso.storeData("activePart", false);
  946.                     
  947.         --wso.setState("waitIntimate");
  948.         thisWso.setState("waitIntimate");
  949.     end )
  950.     
  951.     
  952.     
  953.     
  954.     
  955.     
  956.     
  957.     
  958.     -- kissBed
  959.     onMsg("kissBed", function(msg)
  960.         print("character onMsg kissBed");
  961.         -- get character who initiated this action
  962.         local character = getStateObjectFromID(msg.sender);
  963.         
  964.         if not getInteractionBed(this, character) then
  965.             instantAbort(character)
  966.             return
  967.         end
  968.                         
  969.         character.walkSO.storeData("activePart", true);
  970.         this.walkSO.storeData("activePart", false);
  971.                 
  972.         sendMsg("kissBed", character.walkSO);        
  973.         sendMsg("kissBed", this.walkSO);        
  974.     end )    
  975.     
  976.     -- pettingBed
  977.     onMsg("pettingBed", function(msg)
  978.         print("character onMsg pettingBed");
  979.         -- get character who initiated this action
  980.         local character = getStateObjectFromID(msg.sender);
  981.                 
  982.         if not getInteractionBed(this, character) then
  983.             instantAbort(character)
  984.             return
  985.         end
  986.                         
  987.         character.walkSO.storeData("activePart", true);
  988.         this.walkSO.storeData("activePart", false);
  989.                 
  990.         sendMsg("pettingBed", character.walkSO);        
  991.         sendMsg("pettingBed", this.walkSO);        
  992.     end )
  993.         
  994.     -- sexBed
  995.     onMsg("sexBed", function(msg)
  996.         print("character onMsg sexBed");
  997.         -- get character who initiated this action
  998.         local character = getStateObjectFromID(msg.sender);
  999.         
  1000.         if not getInteractionBed(this, character) then
  1001.             instantAbort(character)
  1002.             return
  1003.         end
  1004.                         
  1005.         character.walkSO.storeData("activePart", true);
  1006.         this.walkSO.storeData("activePart", false);
  1007.                 
  1008.         sendMsg("sexBed", character.walkSO);        
  1009.         sendMsg("sexBed", this.walkSO);    
  1010.  
  1011.     end )    
  1012.     
  1013.     
  1014.     
  1015.     
  1016.     
  1017.     -- holdNice
  1018.     onMsg("holdNice", function(msg)
  1019.         -- get the game object server
  1020.         local gameObjectServer = getGameObjectServer();
  1021.         -- get character who initiated this action
  1022.         local character = getStateObjectFromID(msg.sender);        
  1023.         
  1024.         --if (instantAbortIfNotIdle(character, this)) then return end;
  1025.         if instantAbortIfUnhappy(character, msg.name, this) then return end;        
  1026.         
  1027.         -- check if the activity is possible
  1028.         --if (activityPossible(character, msg.name, this) and isIdle(this)) then
  1029.         
  1030.         local possible, result, activity = activityPossible(character, msg.name, this)
  1031.         
  1032.         -- don't care if timeslot is not fulfilled
  1033.         if (possible or enumCompare(result, TIMESLOT)) then
  1034.         
  1035.             -- walk to the interaction point
  1036.             local interactionPoint = findInteractionPoint("hug", character);
  1037.             if (interactionPoint) then
  1038.                 -- get the walk state objects
  1039.                 local wso = character.walkSO;
  1040.                 local thisWso = this.walkSO;
  1041.                 -- create state machine contexts
  1042.                 local wsoContext =  StateMachineContext();
  1043.                 local thisWsoContext = StateMachineContext();
  1044.                 -- store the partners
  1045.                 wsoContext.storeStateObject("partner", thisWso);
  1046.                 wsoContext.storeData("activePart", true);
  1047.                 thisWsoContext.storeStateObject("partner", wso);
  1048.                 thisWsoContext.storeData("activePart", false);
  1049.                 thisWsoContext.storeData("waitLong", isIdle(this));
  1050.                 -- start action for other character
  1051.                 if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  1052.                     -- wso.queueMessage("waitForChar", this, "holdNice", wsoContext);
  1053.                     wso.queueStateMachine("interaction.holdNice", this, wsoContext);
  1054.                     
  1055.                     -- queue walk and state change msg for this(passive) character
  1056.                     local passiveMsg = QueuedMessage();
  1057.                     -- passiveMsg.set("waitForChar", this.getUniqueID(), "holdNice", thisWsoContext);
  1058.                     passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.holdNice", thisWsoContext);
  1059.  
  1060.                     print("-----------------------> passive character pushWalkActionPoint");
  1061.                     local walkQueueEntry = this.pushWalkActionPoint("pm_holdNice", interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);
  1062.  
  1063.  
  1064.                     
  1065. --                    -- start action for this character
  1066. --                    if (thisWso.walkToActionPoint(interactionPoint.getPassiveActionPoint())) then
  1067. --                        thisWso.queueMessage("waitForChar", this, "holdNice", thisWsoContext);
  1068. --                    else
  1069. --                        print("no path found");
  1070. --                        instantAbort(this, EMOTICON_NOPATH, "emoThink")
  1071. --                    end
  1072.                 else
  1073.                     print("no path found");
  1074.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  1075.                 end
  1076.             else
  1077.                 print("no interaction point found");
  1078.                 instantAbort(character, EMOTICON_CANNOT, "emoThink")
  1079.             end
  1080.         else
  1081.             -- activity not possible
  1082.             print(msg.name .. " not possible");
  1083.             sendMsg("sad", character.mimicSO);
  1084.             
  1085.             local emoticon;
  1086.             if (enumCompare(result, NO_CONDITION)) then
  1087.                 emoticon = conditionToEmoticon(activity.getUnfulfilledCondition());
  1088.             else
  1089.                 emoticon = EMOTICON_SAD
  1090.             end
  1091.             instantAbort(character, emoticon, "emoRefuseChar", this)
  1092.             
  1093.             -- show emoticon if activity was not possible on partner
  1094.             if (enumCompare(result, NO_PARTNERCONDITION) or enumCompare(result, NO_PARTNERSATISFACTION)) then
  1095.                 local emoticon;
  1096.                 local unfulfilledPartnerCondition = activity.getUnfulfilledPartnerCondition();
  1097.                 if (not enumCompare(unfulfilledPartnerCondition, NEED_NONE)) then
  1098.                     emoticon = conditionToEmoticon(unfulfilledPartnerCondition);
  1099.                 else
  1100.                     emoticon = EMOTICON_SAD
  1101.                 end
  1102.                 
  1103.                 this.setEmoticon(emoticon, EMOTICON_DELAY);
  1104.             end
  1105.         end
  1106.     end )
  1107.     
  1108.         
  1109.     
  1110.     
  1111.     
  1112.     
  1113.     -- holdBehind
  1114.     onMsg("holdBehind", function(msg)
  1115.         -- get the game object server
  1116.         local gameObjectServer = getGameObjectServer();
  1117.         -- get character who initiated this action
  1118.         local character = getStateObjectFromID(msg.sender);
  1119.         
  1120.         --if (instantAbortIfNotIdle(character, this)) then return end;        
  1121.         if instantAbortIfUnhappy(character, msg.name, this) then return end;        
  1122.         
  1123.         local possible, result, activity = activityPossible(character, msg.name, this)
  1124.         
  1125.         -- check if the activity is possible
  1126.         -- don't care if timeslot is not fulfilled
  1127.         if (possible or enumCompare(result, TIMESLOT)) then
  1128.         
  1129.             -- walk to the interaction point
  1130.             local interactionPoint = findInteractionPoint("behind", character);
  1131.             if (interactionPoint) then
  1132.                 -- get the walk state objects
  1133.                 local wso = character.walkSO;
  1134.                 local thisWso = this.walkSO;
  1135.                 -- create state machine contexts
  1136.                 local wsoContext =  StateMachineContext();
  1137.                 local thisWsoContext = StateMachineContext();
  1138.                 -- store the partners
  1139.                 wsoContext.storeStateObject("partner", thisWso);
  1140.                 wsoContext.storeData("activePart", true);
  1141.                 thisWsoContext.storeStateObject("partner", wso);
  1142.                 thisWsoContext.storeData("activePart", false);
  1143.                 thisWsoContext.storeData("waitLong", isIdle(this));
  1144.                 -- start action for other character
  1145.                 if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  1146.                     -- wso.queueMessage("waitForChar", this, "holdBehind", wsoContext);
  1147.                     wso.queueStateMachine("interaction.holdBehind", this, wsoContext);
  1148.                                         
  1149.                     -- queue walk and state change msg for this(passive) character
  1150.                     local passiveMsg = QueuedMessage();
  1151.                     passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.holdBehind", thisWsoContext);
  1152.  
  1153.                     local walkQueueEntry = this.pushWalkActionPoint("pm_holdBehind", interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);                    
  1154.  
  1155.                                         
  1156. --                    -- start action for this character
  1157. --                    if (thisWso.walkToActionPoint(interactionPoint.getPassiveActionPoint())) then
  1158. --                        thisWso.queueMessage("waitForChar", this, "holdBehind", thisWsoContext);
  1159. --                    else
  1160. --                        print("no path was found");
  1161. --                        this.setEmoticon(EMOTICON_NOPATH, EMOTICON_DELAY);
  1162. --                        sendMsg("emoThink", this.walkSO);
  1163. --                    end
  1164.                 else
  1165.                     print("no path was found");
  1166.                     instantAbort(character, EMOTICON_NOPATH, "emoThink")
  1167.                 end
  1168.             else
  1169.                 print("no interaction point found");
  1170.                 instantAbort(character, EMOTICON_CANNOT, "emoThink")
  1171.             end
  1172.         else
  1173.             -- activity not possible
  1174.             print(msg.name .. " not possible");
  1175.             sendMsg("sad", character.mimicSO);
  1176.             
  1177.             local emoticon;
  1178.             if (enumCompare(result, NO_CONDITION)) then
  1179.                 emoticon = conditionToEmoticon(activity.getUnfulfilledCondition());
  1180.             else
  1181.                 emoticon = EMOTICON_SAD
  1182.             end
  1183.             instantAbort(character, emoticon, "emoRefuseChar", this)
  1184.             
  1185.             -- show emoticon if activity was not possible on partner
  1186.             if (enumCompare(result, NO_PARTNERCONDITION) or enumCompare(result, NO_PARTNERSATISFACTION)) then
  1187.                 local emoticon;
  1188.                 local unfulfilledPartnerCondition = activity.getUnfulfilledPartnerCondition();
  1189.                 if (not enumCompare(unfulfilledPartnerCondition, NEED_NONE)) then
  1190.                     emoticon = conditionToEmoticon(unfulfilledPartnerCondition);
  1191.                 else
  1192.                     emoticon = EMOTICON_SAD
  1193.                 end
  1194.                 
  1195.                 this.setEmoticon(emoticon, EMOTICON_DELAY);
  1196.             end
  1197.         end
  1198.     end )
  1199.     
  1200.     
  1201. --    onMsg("imBackAtHome", function(msg)
  1202. --        if (this.getRememberGift() == true) and (holdObject(this, "gift")) then
  1203. --            print("looking for partner to give the gift")
  1204. --            local partner = getStateObjectFromID(msg.sender);
  1205. --            this.setRememberGift(false);                                
  1206. --            if (partner) then
  1207. --                sendMsg("giveGift", partner);
  1208. --            end            
  1209. --        end
  1210. --    end )
  1211.     
  1212.     -- giveGift
  1213.     onMsg("giveGift", function(msg)
  1214.     
  1215.         -- get the game object server
  1216.         local gameObjectServer = getGameObjectServer();
  1217.         -- get character who initiated this action
  1218.         local character = getStateObjectFromID(msg.sender);
  1219.         
  1220.         print("onMsg giveGift from " .. character.getCharacterName() .. " to " .. this.getCharacterName());        
  1221.  
  1222.         --if (instantAbortIfNotIdle(character, this)) then return end;
  1223.  
  1224.         
  1225.         -- check if the activity is possible    
  1226.         local possible, result, activity = activityPossible(character, msg.name, this);
  1227.         
  1228.         -- don't care if timeslot is not fulfilled
  1229.         if (possible or enumCompare(result, TIMESLOT)) then
  1230.                 
  1231.             if (holdsObject(character, "gift")) then                
  1232.                 -- walk to the interaction point
  1233.                 local interactionPoint = findInteractionPoint("talk", character);
  1234.                 if (interactionPoint) then
  1235.                     -- get the walk state objects
  1236.                     local wso = character.walkSO;
  1237.                     local thisWso = this.walkSO;
  1238.                     -- create state machine contexts
  1239.                     local wsoContext =  StateMachineContext();
  1240.                     local thisWsoContext =  StateMachineContext();
  1241.                     -- store the partners
  1242.                     wsoContext.storeStateObject("partner", thisWso);
  1243.                     wsoContext.storeData("activePart", true);
  1244.                     thisWsoContext.storeStateObject("partner", wso);
  1245.                     thisWsoContext.storeData("activePart", false);
  1246.                     thisWsoContext.storeData("waitLong", isIdle(this));
  1247.                     -- start action for other character
  1248.                     if (wso.walkToActionPoint(interactionPoint.getActiveActionPoint())) then
  1249.                         -- wso.queueMessage("waitForChar", this, "giveGift", wsoContext);
  1250.                         wso.queueStateMachine("interaction.giveGift", this, wsoContext);
  1251.                                         
  1252.                         -- queue walk and state change msg for this(passive) character
  1253.                         local passiveMsg = QueuedMessage();
  1254.                         -- passiveMsg.set("waitForChar", this.getUniqueID(), "giveGift", thisWsoContext);
  1255.                         passiveMsg.set(Message.MSG_RESERVED_EnterStateMachine, this.getUniqueID(), "interaction.giveGift", thisWsoContext);
  1256.  
  1257.                         print("-----------------------> passive character pushWalkActionPoint");
  1258.                         local walkQueueEntry = this.pushWalkActionPoint("pm_giveGift", interactionPoint.getPassiveActionPoint(), false, passiveMsg, true);                    
  1259.  
  1260.                                         
  1261. --                        -- start action for this character
  1262. --                        if (thisWso.walkToActionPoint(interactionPoint.getPassiveActionPoint())) then
  1263. --                            thisWso.queueMessage("waitForChar", this, "giveGift", thisWsoContext);
  1264. --                        else
  1265. --                            print("no path found");
  1266. --                            instantAbort(this, EMOTICON_NOPATH, "emoThink")
  1267. --                        end
  1268.                     else
  1269.                         print("no path found");
  1270.                         instantAbort(character, EMOTICON_NOPATH, "emoThink")
  1271.                     end
  1272.                 else
  1273.                     print("no interaction point found");
  1274.                     instantAbort(character, EMOTICON_CANNOT, "emoThink")
  1275.                 end
  1276.             else
  1277.                 print("no gift to give")
  1278.                 sendMsg("sad", character.mimicSO);
  1279.                 instantAbort(character, EMOTICON_CANNOT, "emoThink")
  1280.             end
  1281.         else
  1282.             -- activity not possible
  1283.             print(msg.name .. " not possible");
  1284.             sendMsg("sad", character.mimicSO);
  1285.             
  1286.             local emoticon;
  1287.             if (enumCompare(result, NO_CONDITION)) then
  1288.                 emoticon = conditionToEmoticon(activity.getUnfulfilledCondition());
  1289.             else
  1290.                 emoticon = EMOTICON_SAD
  1291.             end
  1292.             instantAbort(character, emoticon, "emoRefuseChar", this)
  1293.             
  1294.             -- show emoticon if activity was not possible on partner
  1295.             if (enumCompare(result, NO_PARTNERCONDITION) or enumCompare(result, NO_PARTNERSATISFACTION)) then
  1296.                 local emoticon;
  1297.                 local unfulfilledPartnerCondition = activity.getUnfulfilledPartnerCondition();
  1298.                 if (not enumCompare(unfulfilledPartnerCondition, NEED_NONE)) then
  1299.                     emoticon = conditionToEmoticon(unfulfilledPartnerCondition);
  1300.                 else
  1301.                     emoticon = EMOTICON_SAD
  1302.                 end
  1303.                 
  1304.                 this.setEmoticon(emoticon, EMOTICON_DELAY);
  1305.             end
  1306.         end
  1307.     end )    
  1308.     
  1309.     
  1310.     
  1311.     -- play as this char
  1312.     onMsg("playAsThis", function(msg)
  1313.         getGameObjectServer().setCurrentCharacter(this);
  1314.     end )
  1315.     
  1316. endStateMachine()
  1317.