//*************************************************************** // Copyright 2008 Centre For Advanced Spatial Analysis, UCL // // Author: Joel Dearden, University College London // // Contact: j.dearden@ucl.ac.uk // // Joel Dearden, // Centre for Advanced Spatial Analysis, // University College London, // 1-19 Torrington Place, // London, // WC1E 7HB // // // This file is part of SLSegregationModel. // // SLSegregationModel is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // SLSegregationModel is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with SLSegregationModel. If not, see . // //*************************************************************** integer empty = TRUE; integer chatToHouse = -92822; integer chatFromHouse = -92823; float movePosAccuracy = 0.2; float neighbourScanRange = 0.85; integer segPref; //percentage - set by start parameter integer redNeighbours = -1; integer blueNeighbours = -1; checkMoveIn(vector moveInPos) { if(roughlySamePos(moveInPos)) { empty = FALSE; } } checkMoveOut(vector moveOutPos) { if(roughlySamePos(moveOutPos)) { empty = TRUE; } } integer roughlySamePos(vector targetPos) { vector myPos = llGetPos(); if(llFabs(targetPos.x - myPos.x) < movePosAccuracy) { if(llFabs(targetPos.y - myPos.y) < movePosAccuracy) { if(llFabs(targetPos.z - myPos.z) < movePosAccuracy) { return TRUE; } } } return FALSE; } default { on_rez(integer start_param) { //house has been created by controller //save segPref segPref = start_param; //it is empty //llSetText("segPref=" + (string) segPref, <0,0,0>, 1.0); state waiting; } } state reset { state_entry() { empty = TRUE; state waiting; } } state waiting { state_entry() { llListen(chatToHouse, "", NULL_KEY, ""); } listen(integer channel, string name, key id, string message) { //messages to listen for if(channel == chatToHouse) { //messages relevant to an all houses... //controller reset if(message == "rst") { state reset; } if(message == "die") { llDie(); } if(empty == TRUE) { //messages relevant to an empty house... //agent moving in if(llGetSubString(message, 0, 2) == "mi:") { checkMoveIn((vector) llGetSubString(message, 3, -1)); return; } //agent looking for a house if(llGetSubString(message, 0, 2) == "lh:") { string agentColour = llGetSubString(message, 3, -1); if(agentColour == "red") { state processRedHouseRequest; } else { state processBlueHouseRequest; } } } else { //messages relevant to an occupied house... //agent moving out if(llGetSubString(message, 0, 2) == "mo:") { checkMoveOut((vector) llGetSubString(message, 3, -1)); return; } } } } } state processRedHouseRequest { state_entry() { //listen for controller messages llListen(chatToHouse, "", NULL_KEY, ""); //overview of this state: //1) get list of red agents //2) get list of blue agents //3) compare percentages //4) send message if its ok redNeighbours = -1; blueNeighbours = -1; llSensor("red_agent", NULL_KEY, PASSIVE | SCRIPTED, neighbourScanRange, PI); } listen(integer channel, string name, key id, string message) { //messages to listen for if(channel == chatToHouse) { //messages relevant to an all houses... //controller reset if(message == "rst") { state reset; } if(message == "die") { llDie(); } } } no_sensor() { if(redNeighbours == -1) { //red scan result redNeighbours = 0; llSensor("blue_agent", NULL_KEY, PASSIVE | SCRIPTED, neighbourScanRange, PI); } else { //blue scan result blueNeighbours = 0; //compare percentages integer totalNeighbours = redNeighbours + blueNeighbours; if(totalNeighbours == 0) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:0%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { float redPercentage = ((float)redNeighbours / (float)totalNeighbours) * 100; if(redPercentage >= segPref) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:" + (string) redPercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { //the house is NOT OK //let agent know it won't be happy here - don't need to send position //llSetText("BAD:" + (string) redPercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "bh"); } } state waiting; } } sensor(integer num_detected) { if(redNeighbours == -1) { //red scan result redNeighbours = num_detected; llSensor("blue_agent", NULL_KEY, PASSIVE | SCRIPTED, neighbourScanRange, PI); } else { //blue scan result blueNeighbours = num_detected; //compare percentages integer totalNeighbours = redNeighbours + blueNeighbours; if(totalNeighbours == 0) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:0%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { float redPercentage = ((float)redNeighbours / (float)totalNeighbours) * 100; if(redPercentage >= segPref) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:" + (string) redPercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { //the house is NOT OK //let agent know it won't be happy here - don't need to send position //llSetText("BAD:" + (string) redPercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "bh"); } } state waiting; } } } state processBlueHouseRequest { state_entry() { //listen for controller messages llListen(chatToHouse, "", NULL_KEY, ""); //overview of this state: //1) get list of red agents //2) get list of blue agents //3) compare percentages //4) send message if its ok redNeighbours = -1; blueNeighbours = -1; llSensor("red_agent", NULL_KEY, PASSIVE | SCRIPTED, neighbourScanRange, PI); } listen(integer channel, string name, key id, string message) { //messages to listen for if(channel == chatToHouse) { //messages relevant to an all houses... //controller reset if(message == "rst") { state reset; } if(message == "die") { llDie(); } } } no_sensor() { if(redNeighbours == -1) { //red scan result redNeighbours = 0; llSensor("blue_agent", NULL_KEY, PASSIVE | SCRIPTED, neighbourScanRange, PI); } else { //blue scan result blueNeighbours = 0; //compare percentages integer totalNeighbours = redNeighbours + blueNeighbours; if(totalNeighbours == 0) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:0%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { float bluePercentage = ((float)blueNeighbours / (float)totalNeighbours) * 100; if(bluePercentage >= segPref) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:" + (string) bluePercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { //the house is NOT OK //let agent know it won't be happy here - don't need to send position //llSetText("BAD:" + (string) bluePercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "bh"); } } state waiting; } } sensor(integer num_detected) { if(redNeighbours == -1) { //red scan result redNeighbours = num_detected; llSensor("blue_agent", NULL_KEY, PASSIVE | SCRIPTED, neighbourScanRange, PI); } else { //blue scan result blueNeighbours = num_detected; //compare percentages integer totalNeighbours = redNeighbours + blueNeighbours; if(totalNeighbours == 0) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:0%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { float bluePercentage = ((float)blueNeighbours / (float)totalNeighbours) * 100; if(bluePercentage >= segPref) { //the house is OK //let agent know it can move in here and be happy //llSetText("GOOD:" + (string) bluePercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "gh:" + (string)llGetPos()); } else { //the house is NOT OK //let agent know it won't be happy here - don't need to send position //llSetText("BAD:" + (string) bluePercentage + "%", <0,0,0>, 1.0); llSay(chatFromHouse, "bh"); } } state waiting; } } }