00001                                    Help Index
00002 -] Instance Methods
00003   -] C2DPoint
00004     CONSTRUCTOR
00005     getX
00006     yPos
00007   -] C3DLine
00008     CONSTRUCTOR
00009     hitsThing
00010   -] C3DPoint
00011     CONSTRUCTOR
00012   -] C3DThing
00013     CONSTRUCTOR
00014     SETX
00015     SETY
00016     SETZ
00017     YPOS
00018     addMomX
00019     addMomY
00020     addMomZ
00021     afterRestore
00022     angleBetween
00023     assign_id
00024     beforeRestore
00025     bestHit
00026     damage
00027     die
00028     dropItem
00029     getAngle
00030     getHealth
00031     getName
00032     isOverEdge
00033     lookForHealTarget
00034     lookForTarget
00035     moveGoesOverEdge
00036     newChaseDirection
00037     newdirection2
00038     onGround
00039     rayHitsTarget
00040     rayHitsTargetAutoAim
00041     sendToStream
00042     setAngle
00043     setName
00044     swimAtAngleAtAngle2
00045     wander
00046     wanderFly
00047     wanderWithJump
00048     xPos
00049     zPos
00050     hitsThing:(builitn)
00051     pathFinderAngleTowardsThing:withJump:(builitn)
00052     move:atAngle:(builitn)
00053     canSeeThing:(builitn)
00054     isOnGround(builitn)
00055   -] C3DThingTemplate
00056     CONSTRUCTOR
00057     SETNAME
00058     sendToStream
00059     setBack
00060     setFront
00061     setside
00062     updateProperties
00063     save(builitn)
00064   -] C3DWorldClient
00065     CONSTRUCTOR
00066     armUpdates
00067     handleMessage
00068     new
00069     newConnectionTo
00070     receiveThings
00071     sendEditCeilForBlock
00072     sendEditFloorForBlock
00073     sendEditPoo
00074     sendMessageWithType
00075     sendPickupToClient
00076     sendPiss
00077     sendPlaceBlock
00078     sendPlaceDoor
00079     sendPlaceThing
00080     sendPlayerAttackToServer
00081     sendPlayerMovement
00082     sendProjectile
00083   -] C3DWorldManager
00084     ADDNEWTHING
00085     ADDTHING
00086     ADDTHINGTEMPLATE
00087     CONSTRUCTOR
00088     GETPLAYER
00089     GETTHINGTEMPLATE
00090     GRAVITY
00091     UPDATE
00092     addClient
00093     addDoor
00094     addFloorStain
00095     addStain
00096     addTileTemplate
00097     afterRestore
00098     animate
00099     beforeSave
00100     connectToServerAtPort
00101     doorInRadius
00102     getClientFromPlayer
00103     getObstaclesInRadius
00104     getPlatformHeight
00105     handleMessageForClient
00106     handlePowerups
00107     hostGameAtPort
00108     isObstacleAtXAtY
00109     lighting
00110     newExplosionLight
00111     newGrid
00112     newLandscape
00113     newParticle
00114     newParticleWithSplat
00115     pause
00116     recv3DThing
00117     recv3DThingTemplate
00118     recvBlockEdit
00119     removeThing
00120     restoreBlocksFromString
00121     saveBlocksToString
00122     sendLinestoClient
00123     sendThingsToClient
00124     thingsInPath
00125     unpause
00126     updateLines
00127     loadLevelFromBlob(builitn)
00128     restoreBlocksFromString:withWidth:withHeight:(builitn)
00129     emptyWorldWithWidth:withHeight:(builitn)
00130     getTileAtX:atY:atZ:(builitn)
00131     setTile:atX:atY:atZ:(builitn)
00132     tileIsLiquidAtX:atY:atZ:(builitn)
00133     pointToScreenZAtX:atY:atZ:(builitn)
00134     pointToScreenYAtX:atY:atZ:(builitn)
00135     pointToScreenXAtX:atY:atZ:(builitn)
00136     getQuestChatBot:(builitn)
00137     noiseSoundForTime:withMin:withMax:(builitn)
00138     sweepSoundForTime:withMin:withMax:(builitn)
00139     getShiftKey(builitn)
00140     updateParticles(builitn)
00141     width(builitn)
00142     skylight:(builitn)
00143     basicNewParticleAtX:atY:atZ:withSpread:withColor:withSplatLump:(builitn)
00144     saveBlocksToString(builitn)
00145     screenTile(builitn)
00146     basicNewParticleAtX:atY:atZ:withSpread:withColor:(builitn)
00147     loadLevelFromBlob:(builitn)
00148     screenCoordToDist(builitn)
00149     saveLevelToBlob(builitn)
00150     height(builitn)
00151     screenTileSide(builitn)
00152     removeFromGrid:(builitn)
00153     physics(builitn)
00154     getThingsInRadiusFromX:fromY:withRadius:(builitn)
00155     updateThingPos:(builitn)
00156     selectQuest(builitn)
00157     screenCoordToX(builitn)
00158     screenCoordToY(builitn)
00159     screenCoordToZ(builitn)
00160     saveLevelToBlob:(builitn)
00161   -] C3DWorldShell
00162     CONSTRUCTOR
00163   -] CAlien
00164     CONSTRUCTOR
00165     damageFrom
00166     update
00167   -] CAssBird
00168     CONSTRUCTOR
00169     animate
00170     damageFrom
00171     update
00172   -] CAsyncStream
00173     CONSTRUCTOR
00174     acceptWCallback
00175     close
00176     newConnectionTo
00177     newServerAt
00178     readBytesWithBlock
00179     readLineWithCAllback
00180     readU32WCB
00181     write
00182     writeLine
00183     writeU32
00184   -] CBigKey
00185     CONSTRUCTOR
00186   -] CBigKeyPickup
00187     CONSTRUCTOR
00188   -] CBlockEditShell
00189     CONSTRUCTOR
00190   -] CCeilStain
00191     CONSTRUCTOR
00192   -] CCeilWallStain
00193     CONSTRUCTOR
00194   -] CCyberPoop
00195     CONSTRUCTOR
00196     damageFrom
00197     update
00198   -] CDayNight
00199     CONSTRUCTOR
00200     update
00201   -] CDayNightStar
00202     CONSTRUCTOR
00203   -] CDogTongue
00204     CONSTRUCTOR
00205     update
00206   -] CDoor
00207     CONSTRUCTOR
00208     activate
00209     activateBy
00210     activateByTag
00211     update
00212   -] CDoorItem
00213     CONSTRUCTOR
00214     fire
00215   -] CDoorShell
00216     CONSTRUCTOR
00217     fire
00218   -] CEggplantMan
00219     CONSTRUCTOR
00220     animate
00221     damageFrom
00222     grabbedThing
00223     update
00224     updateGrab
00225   -] CEliza
00226     CONSTRUCTOR
00227     Message
00228     addReasm
00229     addSynonymFor
00230     getFocus
00231     getHello
00232     getQuit
00233     getSynonym
00234     getSynonyms
00235     inherit_quest
00236     message0
00237     setFocus
00238     setHello
00239     setQuit
00240     setSynonyms
00241   -] CElizaReasm
00242     CONSTRUCTOR
00243     acceptsFlags
00244     getGotoText
00245     initFromString
00246     matchWords
00247     matchWords0
00248     modifyFlags
00249     reassemble
00250     setAddFlags
00251     setIsValidBlock
00252     setNeedFlags
00253     setOnCompleteBlock
00254     setRemoveFlags
00255     setResult
00256   -] CEnemyEdit
00257     CONSTRUCTOR
00258     fire
00259   -] CEnemyEditShell
00260     CONSTRUCTOR
00261   -] CEnergyBall
00262     CONSTRUCTOR
00263     checkExplode
00264     explode
00265   -] CEnergyGun
00266     CONSTRUCTOR
00267     animate
00268     fire
00269   -] CEnergyGunPickup
00270     CONSTRUCTOR
00271   -] CFloorStain
00272     CONSTRUCTOR
00273     getTileX
00274     getTileY
00275     putStain
00276   -] CFrogArray
00277     ADDALL
00278     COLLECT
00279     CONSTRUCTOR
00280     COPYFROM
00281     DETECT
00282     DO
00283     FIRST
00284     INCLUDES
00285     INDEXOF
00286     ISEMPTY
00287     LAST
00288     OCCURANCESOF
00289     PRINTSTRING
00290     REJECT
00291     REMOVEALL
00292     SELECT
00293     has
00294     sort
00295     size(builitn)
00296     ~=(builitn)
00297     remove:(builitn)
00298     =(builitn)
00299     copy(builitn)
00300     at:(builitn)
00301     copyFrom:to:(builitn)
00302     removeAt:(builitn)
00303     add:(builitn)
00304     at:put:(builitn)
00305   -] CFrogBin
00306     CONSTRUCTOR
00307   -] CFrogBlobFile
00308     CONSTRUCTOR
00309     readLump:(builitn)
00310     open:(builitn)
00311   -] CFrogBlock
00312     CONSTRUCTOR
00313     on:do:(builitn)
00314     value(builitn)
00315     whileFalse:(builitn)
00316     whileTrue:(builitn)
00317     value:value:value:value:value:(builitn)
00318     value:value:value:value:(builitn)
00319     value:value:value:(builitn)
00320     value:value:(builitn)
00321     value:(builitn)
00322   -] CFrogChr
00323     CONSTRUCTOR
00324     COPY
00325     PRINTSTRING
00326     uppercase(builitn)
00327     isWhitespace(builitn)
00328     asciiValue(builitn)
00329     isAlphaNumeric(builitn)
00330     isDisplayable(builitn)
00331     isNumber(builitn)
00332   -] CFrogClass
00333     CONSTRUCTOR
00334     asString(builitn)
00335   -] CFrogDick
00336     CONSTRUCTOR
00337     animate
00338     fire
00339   -] CFrogDictionary
00340     CONSTRUCTOR
00341     keys
00342     at:put:(builitn)
00343     doKeys:(builitn)
00344     at:(builitn)
00345   -] CFrogDivideError
00346     CONSTRUCTOR
00347   -] CFrogError
00348     CONSTRUCTOR
00349     PRINTSTRING
00350   -] CFrogImg
00351     CONSTRUCTOR
00352     afterRestore
00353     setGraphics:(builitn)
00354     asString(builitn)
00355     width(builitn)
00356     height(builitn)
00357     setGraphicsFromString:(builitn)
00358   -] CFrogNPC
00359     CONSTRUCTOR
00360     UPDATE
00361     animate
00362     damage
00363     getChatBot
00364     setChatBot
00365   -] CFrogNum
00366     ABS
00367     BETWEENAND
00368     CONSTRUCTOR
00369     COPY
00370     DIVIDE
00371     MAX
00372     MIN
00373     PRINTSTRING
00374     REM1
00375     REM2
00376     TODO
00377     and
00378     arg
00379     asInteger
00380     not
00381     or
00382     sign
00383     squared
00384     asCharactor(builitn)
00385     bitAt:(builitn)
00386     negated(builitn)
00387     basicRem:(builitn)
00388     arctan(builitn)
00389     tan(builitn)
00390     arcsin(builitn)
00391     sin(builitn)
00392     sqrt(builitn)
00393     ceil(builitn)
00394     bitInvert(builitn)
00395     basicIntDiv:(builitn)
00396     arccos(builitn)
00397     cos(builitn)
00398     &(builitn)
00399     *(builitn)
00400     +(builitn)
00401     -(builitn)
00402     /(builitn)
00403     <(builitn)
00404     =(builitn)
00405     >(builitn)
00406     ^(builitn)
00407     |(builitn)
00408     log(builitn)
00409     basicDiv:(builitn)
00410     ifTrue:(builitn)
00411     raisedTo:(builitn)
00412     timesRepeat:(builitn)
00413     ifTrue:ifFalse:(builitn)
00414     ifFalse:(builitn)
00415     <=(builitn)
00416     asInteger(builitn)
00417     >=(builitn)
00418     floor(builitn)
00419     ~=(builitn)
00420     round(builitn)
00421   -] CFrogRandom
00422     CONSTRUCTOR
00423     INIT2
00424     NEXT
00425   -] CFrogStr
00426     CONSTRUCTOR
00427     DO
00428     HASH
00429     PRINTSTRING
00430     uppercase
00431     wrap
00432     copy(builitn)
00433     at:(builitn)
00434     restoreThingFromSaveFile(builitn)
00435     ~=(builitn)
00436     add:(builitn)
00437     restoreThing(builitn)
00438     copyFrom:to:(builitn)
00439     removeAt:(builitn)
00440     compare:(builitn)
00441     at:put:(builitn)
00442     indexOf:(builitn)
00443     asInteger(builitn)
00444     remove:(builitn)
00445     size(builitn)
00446     ,(builitn)
00447     =(builitn)
00448   -] CFrogSymbol
00449     CONSTRUCTOR
00450   -] CFrogThing
00451     CONSTRUCTOR
00452     getHealth
00453     saveThingToSaveFile:(builitn)
00454     isNil(builitn)
00455     class(builitn)
00456     saveThing(builitn)
00457     ~=(builitn)
00458     hasClass:(builitn)
00459     show(builitn)
00460     =(builitn)
00461     basicSaveThing(builitn)
00462   -] CFrogThread
00463     CONSTRUCTOR
00464     kill(builitn)
00465   -] CFrogTime
00466     CONSTRUCTOR
00467     asSeconds
00468   -] CFrogTongue
00469     CONSTRUCTOR
00470     eatTarget
00471     update
00472   -] CFrogUndefined
00473     CONSTRUCTOR
00474   -] CGun1
00475     CONSTRUCTOR
00476     animate
00477     fire
00478   -] CGun1Pickup
00479     CONSTRUCTOR
00480   -] CHandItem
00481     CONSTRUCTOR
00482     addToPlayerAgain
00483     aimAt
00484     beforeSave
00485     getAmmo
00486     getMaxAmmo
00487     setAmmoi
00488     setGraphics
00489     setMaxAmmo
00490   -] CHealthPickup
00491     CONSTRUCTOR
00492   -] CKnife
00493     CONSTRUCTOR
00494     animate
00495     fire
00496   -] CLandscapeGenerator
00497     CONSTRUCTOR
00498     newLandscapeFromSeed
00499   -] CLevel
00500     CONSTRUCTOR
00501   -] CLevelEditShell
00502     CONSTRUCTOR
00503   -] CLight
00504     CONSTRUCTOR
00505     update
00506   -] CLightningBolt
00507     CONSTRUCTOR
00508     ShootAtXYZ
00509     update
00510   -] CLightningLink
00511     CONSTRUCTOR
00512   -] CMarkerDrugItem
00513     CONSTRUCTOR
00514     animate
00515     fire
00516   -] CMarkerDrugPickup
00517     CONSTRUCTOR
00518   -] CNetStream
00519     CONSTRUCTOR
00520     recvRemoteCall
00521     remoteCall
00522     sendLine
00523     sendBytes:(builitn)
00524     accept(builitn)
00525     getI32(builitn)
00526     sendU8:(builitn)
00527     getU32(builitn)
00528     getU8(builitn)
00529     close(builitn)
00530     getLine(builitn)
00531     getBytes:(builitn)
00532     sendI32:(builitn)
00533     sendString:(builitn)
00534   -] CNumchucks
00535     CONSTRUCTOR
00536     animate
00537     fire
00538   -] CPickup
00539     CONSTRUCTOR
00540     addToPlayer
00541   -] CPissLink
00542     CONSTRUCTOR
00543     setFrom
00544     setMomX
00545     setMomY
00546     setMomZ
00547     setX
00548     setY
00549     setZ
00550     update
00551   -] CPissStream
00552     CONSTRUCTOR
00553     addLink
00554     setFrom
00555     update
00556   -] CPlayer
00557     CONSTRUCTOR
00558     addInventoryItem
00559     addShellCasing
00560     afterRestore
00561     animate
00562     beforeRestore
00563     chatWith
00564     damageFrom
00565     displayMessage
00566     fireProjectileAtTarget
00567     getAngle
00568     getInventroyItems
00569     getPissStream
00570     jump
00571     makeUI
00572     meleeAttack
00573     nextInventoryItem
00574     pissAtAngle
00575     rangeAttackAtAngleWithDamage
00576     regenUI
00577     removeItem
00578     removeShellCasing
00579     selectItem
00580     selectQuickItemByNum
00581     stopChat
00582     toggleMenu
00583     update
00584   -] CPooka
00585     CONSTRUCTOR
00586   -] CPoopMan
00587     CONSTRUCTOR
00588     damageFrom
00589     update
00590   -] CPoopRocket
00591     CONSTRUCTOR
00592     checkExplode
00593     explode
00594   -] CPoopidex
00595     CONSTRUCTOR
00596     activate
00597     addEntryToCategory
00598     updateScree
00599   -] CPoopidexEntry
00600     CONSTRUCTOR
00601   -] CPoopidexShell
00602     CONSTRUCTOR
00603   -] CPorky
00604     CONSTRUCTOR
00605     animate
00606     damageFrom
00607     update
00608   -] CRocket
00609     CONSTRUCTOR
00610     checkExplode
00611     explode
00612     setFrom
00613   -] CRocketLauncher
00614     CONSTRUCTOR
00615     animate
00616     fire
00617   -] CRocketLauncherPickup
00618     CONSTRUCTOR
00619   -] CShellCasing
00620     CONSTRUCTOR
00621     ejectAt
00622     setGraphics
00623     update
00624   -] CShitItem
00625     CONSTRUCTOR
00626     animate
00627     fire
00628   -] CShitItemPickup
00629     CONSTRUCTOR
00630   -] CShootgun
00631     CONSTRUCTOR
00632     animate
00633     fire
00634   -] CShootgunPickup
00635     CONSTRUCTOR
00636   -] CSmallKey
00637     CONSTRUCTOR
00638   -] CSmallKeyPickup
00639     CONSTRUCTOR
00640   -] CSmallPig
00641     CONSTRUCTOR
00642     animate
00643     damagefrom
00644     update
00645   -] CTalkShell
00646     CONSTRUCTOR
00647   -] CTalker
00648     CONSTRUCTOR
00649     fire
00650   -] CThingEditShell
00651     CONSTRUCTOR
00652   -] CTileTemplate
00653     CONSTRUCTOR
00654     SetFront
00655     setCeil
00656     setfloor
00657     save(builitn)
00658     updateTextures(builitn)
00659   -] CUIBackground
00660     CONSTRUCTOR
00661   -] CUIButton
00662     CONSTRUCTOR
00663     SETBG
00664     SETFG
00665     SETLABEL
00666   -] CUICenter
00667     CONSTRUCTOR
00668   -] CUIChatLog
00669     ADDLINE
00670     CONSTRUCTOR
00671     clear
00672   -] CUIElem
00673     ADDCHILD
00674     CONSTRUCTOR
00675     GETHEIGHT
00676     GETWIDTH
00677     GETX
00678     GETY
00679     ONKEYDOWN
00680     ONLCLICK
00681     ONMSMOVE
00682     ONRCLICK
00683     REMCHILD
00684     SETHEIGHT
00685     SETWIDTH
00686     SETX
00687     SETY
00688     getChildren
00689     onDragEnd
00690     onDragStart
00691     onLeftUp
00692     focus(builitn)
00693     sendEventToUI:(builitn)
00694   -] CUIEvent
00695     CONSTRUCTOR
00696   -] CUIGrid
00697     CONSTRUCTOR
00698     SETSIZE
00699     addItem
00700     addItemAt
00701     dragBegin
00702     dragEnd
00703     removeItem
00704   -] CUIGridItem
00705     CONSTRUCTOR
00706     getCount
00707     getItem
00708     getParentX
00709     getParentY
00710     setCount
00711     setGraphics
00712     setItem
00713     setParent
00714   -] CUIIcon
00715     CONSTRUCTOR
00716     setGraphics
00717   -] CUILabel
00718     CONSTRUCTOR
00719     GETLABEL
00720     SETLABEL
00721   -] CUIList
00722     CONSTRUCTOR
00723   -] CUIMeter
00724     CONSTRUCTOR
00725     SETLABEL
00726     SETMAX
00727     SETVALUE
00728   -] CUINotification
00729     CONSTRUCTOR
00730     addToPoopidex
00731     animate
00732     setIcon
00733   -] CUIScrollBars
00734     CONSTRUCTOR
00735     ONCLICK
00736   -] CUIShell
00737     CONSTRUCTOR
00738     run(builitn)
00739   -] CUITextBar
00740     CONSTRUCTOR
00741     setOnEnter
00742     setOnEscape
00743   -] CUITextPopup
00744     run
00745     CONSTRUCTOR
00746     run
00747   -] CUITree
00748     CONSTRUCTOR
00749     rearrange
00750     setBracnhes
00751   -] CUzi
00752     CONSTRUCTOR
00753     animate
00754     fire
00755   -] CUziPickup
00756     CONSTRUCTOR
00757   -] CWallStain
00758     CONSTRUCTOR
00759     getSide
00760     getTileX
00761     getTileY
00762     newFromDirection
00763     placeAtXYZ
00764     putGraphicsAtXatY
00765     putGraphics:atX:atY:(builitn)
00766     addGraphics:atX:atY:(builitn)
00767     placeAtX:atY:atZ:(builitn)
00768     placeAtX:atY:atZ:atSideX:atSideY:atSideZ:withXOffset:withYOffset:(builitn)
00769   -] CWaterPickup
00770     CONSTRUCTOR
00771   -] CWorldEditBlock
00772     CONSTRUCTOR
00773     afterRestore
00774     altFire
00775     animate
00776     fire
00777     setBlockIndex
00778   -] CWorldEditThing
00779     CONSTRUCTOR
00780     animate
00781     fire
00782   -] CZombie
00783     CONSTRUCTOR
00784     afterRestore
00785     animate
00786     damagefrom
00787     pissTowardsThing
00788     update
00789 -] Class Methods
00790   -] C2DPoint
00791     new
00792   -] C2DThing
00793     new
00794   -] C2DThingTemplate
00795     new
00796   -] C3DLine
00797     new
00798   -] C3DPoint
00799     new
00800   -] C3DThing
00801     new
00802   -] C3DThingTemplate
00803     new
00804   -] C3DWorldClient
00805     newFromStream:
00806   -] C3DWorldManager
00807     new
00808     new
00809   -] C3DWorldShell
00810     new
00811   -] CAlien
00812     new
00813   -] CAssBird
00814     new
00815   -] CAsyncStream
00816     newFromStream:
00817     newServerAt:atPort:
00818     newConnectionTo:atPort:
00819   -] CBigKey
00820     new
00821   -] CBigKeyPickup
00822     new
00823   -] CBlockEditShell
00824     new
00825   -] CCeilStain
00826     new
00827   -] CCeilWallStain
00828     new
00829   -] CCyberPoop
00830     new
00831   -] CDayNight
00832     new
00833   -] CDayNightStar
00834     new
00835   -] CDogTongue
00836     new
00837   -] CDoor
00838     new
00839   -] CDoorItem
00840     new
00841   -] CDoorShell
00842     new
00843   -] CEggplantMan
00844     new
00845   -] CEliza
00846     new
00847     makeResponsesFromArray:
00848     newFromBlob:(builitn)
00849   -] CElizaReasm
00850     new
00851   -] CEnemyEdit
00852     new
00853   -] CEnemyEditShell
00854     new:
00855   -] CEnergyBall
00856     new
00857   -] CEnergyGun
00858     new
00859   -] CEnergyGunPickup
00860     new
00861   -] CFloorStain
00862     new
00863     getTileX
00864   -] CFrogArray
00865     new
00866   -] CFrogBin
00867     new
00868   -] CFrogBlobFile
00869     new:
00870   -] CFrogBlock
00871     new
00872   -] CFrogChr
00873     new
00874   -] CFrogClass
00875     new
00876     fromString:(builitn)
00877   -] CFrogDick
00878     new
00879   -] CFrogDictionary
00880     new
00881   -] CFrogDivideError
00882     new
00883   -] CFrogError
00884     new:
00885   -] CFrogImg
00886     new
00887     get:
00888     newFromEditor(builitn)
00889   -] CFrogNPC
00890     new
00891   -] CFrogNum
00892     asspoodle
00893   -] CFrogRandom
00894     new
00895     new:
00896   -] CFrogStr
00897     new
00898   -] CFrogSymbol
00899     new
00900   -] CFrogThing
00901     new
00902     basicNew(builitn)
00903     name(builitn)
00904   -] CFrogThread
00905     new
00906     spawn:(builitn)
00907     sleep:(builitn)
00908     yield(builitn)
00909   -] CFrogTime
00910     new
00911     unpause(builitn)
00912     setTime:(builitn)
00913     now(builitn)
00914     pause(builitn)
00915   -] CFrogTongue
00916     new
00917   -] CFrogUndefined
00918     new
00919   -] CGun1
00920     new
00921   -] CGun1Pickup
00922     new
00923   -] CHandItem
00924     new
00925   -] CHealthPickup
00926     new
00927   -] CKnife
00928     new
00929   -] CLandscapeGenerator
00930     new
00931   -] CLevel
00932     new
00933   -] CLevelEditShell
00934     new
00935   -] CLight
00936     new
00937   -] CLightningBolt
00938     new
00939   -] CLightningLink
00940     new
00941   -] CMarkerDrugItem
00942     new
00943   -] CMarkerDrugPickup
00944     new
00945   -] CNetStream
00946     new
00947     newConnectionTo:atPort:(builitn)
00948     newServerAt:atPort:(builitn)
00949   -] CNumchucks
00950     new
00951   -] CPickup
00952     new
00953   -] CPissLink
00954     new
00955   -] CPissStream
00956     new
00957   -] CPlayer
00958     new
00959   -] CPooka
00960     new
00961   -] CPoopMan
00962     new
00963   -] CPoopRocket
00964     new
00965   -] CPoopidex
00966     new
00967   -] CPoopidexEntry
00968     newWithTitle:withImg:withText:withCategory:
00969   -] CPoopidexShell
00970     new
00971   -] CPorky
00972     new
00973   -] CRocket
00974     new
00975   -] CRocketLauncher
00976     new
00977   -] CRocketLauncherPickup
00978     new
00979   -] CShellCasing
00980     new
00981   -] CShitItem
00982     new
00983   -] CShitItemPickup
00984     new
00985   -] CShootgun
00986     new
00987   -] CShootgunPickup
00988     new
00989   -] CSmallKey
00990     new
00991   -] CSmallKeyPickup
00992     new
00993   -] CSmallPig
00994     new
00995   -] CTalkShell
00996     new
00997   -] CTalker
00998     new
00999   -] CThingEditShell
01000     new:
01001   -] CTileTemplate
01002     new
01003   -] CUIBackground
01004     new
01005   -] CUIButton
01006     new
01007   -] CUICenter
01008     new
01009   -] CUIChatLog
01010     new
01011   -] CUIElem
01012     new
01013   -] CUIEvent
01014     new
01015   -] CUIGrid
01016     new
01017   -] CUIGridItem
01018     new
01019     getItem
01020   -] CUIIcon
01021     new
01022   -] CUILabel
01023     new
01024   -] CUIList
01025     new
01026     new:
01027   -] CUIMeter
01028     new
01029   -] CUINotification
01030     new:
01031   -] CUIScrollBars
01032     new
01033   -] CUIShell
01034     new
01035   -] CUITextBar
01036     new
01037   -] CUITextPopup
01038     new
01039   -] CUITree
01040     new
01041   -] CUzi
01042     new
01043   -] CUziPickup
01044     new
01045   -] CWallStain
01046     new
01047     newStainAtX:atY:atZ:withGraphicsLump:withSpread:
01048     newStainAtX:atY:atZ:withGraphicsLump:
01049   -] CWaterPickup
01050     new
01051   -] CWorldEditBlock
01052     new:
01053   -] CWorldEditThing
01054     new:
01055   -] CZombie
01056     new
01057     pissTowardsThing
01058 -] Scripts
01059   FrogChat
01060                                   CONSTRUCTOR
01061   
01062   init | |
01063    ^ self
01064   
01065 
01066                                       getX
01067   
01068   getXPos->CFrogNum || ^ x
01069 
01070                                       yPos
01071   
01072   getYPos->CFrogNum || ^ y
01073 
01074                                   CONSTRUCTOR
01075   
01076   init | |
01077     thick _ 4 .
01078     ^ self
01079   
01080 
01081                                    hitsThing
01082   
01083   hitsThing:t=C3DThing
01084   withRadius: within=CFrogNum
01085     ->CFrogNum
01086   |
01087     ab=CFrogArray
01088     ac=CFrogArray
01089     tt=CFrogNum
01090     dot=CFrogBlock
01091     d=CFrogNum
01092     new=CFrogArray 
01093   |
01094     dot _ [:a* :b* |
01095       (a first * b first) +
01096       (a last * b last) +
01097       ((a at:1) * (b at: 1 ))
01098     ] .
01099     'https://gdbooks.gitbooks.io/3dcollisions/content/Chapter1/closest_point_on_ray.html' .
01100     ab _ #( (x -x0) (y - y0) (z - z0 *128)) .
01101     d _ (dot value: ab value: ab) sqrt .
01102     ab _ ab collect: [:n=CFrogNum| n /d] .
01103   
01104     ac _ #( (t->x -x0) (t->y - y0)  (t->z - z0 * 128) ) .
01105   
01106     tt _ (dot value: ac value: ab)/(dot value: ab value: ab ).
01107   
01108   
01109     (tt > (d + within) ) ifTrue: [
01110        ^ 0
01111     ] .
01112     (tt <= 0 ) ifTrue: [
01113        ^ 0
01114     ] .
01115     
01116     new _ #(
01117       (t->x - (tt * ab first + x0 ))
01118       (t->y - (tt * (ab at: 1) + y0 ))
01119       (t->z - (tt * ab last + z0 ))
01120     ) .
01121   
01122     ^ (dot value: new value: new ) < (within * within) . 
01123 
01124                                   CONSTRUCTOR
01125   
01126   init | |
01127    ^ self
01128   
01129 
01130                                   CONSTRUCTOR
01131   
01132   init | |
01133    #world addThing: self .
01134    ^ self
01135   
01136 
01137                                       SETX
01138   
01139   setX: v=CFrogNum ->* || x _ v
01140 
01141                                       SETY
01142   
01143   setY: v=CFrogNum ->* || y _ v
01144 
01145                                       SETZ
01146   
01147   setZ: zz=CFrogNum ->* || z _ zz  dasds _ 123
01148 
01149                                       YPOS
01150   
01151   yPos->CFrogNum | |
01152     ^ y
01153 
01154                                     addMomX
01155   
01156   addMomX: x=CFrogNum ->* || momx _ momx + x
01157 
01158                                     addMomY
01159   
01160   addMomY: x=CFrogNum ->* || momy _ momy + x
01161 
01162                                     addMomZ
01163   
01164   addMomZ: x=CFrogNum ->* || momz _ momz + x
01165 
01166                                   afterRestore
01167   
01168   
01169 
01170                                   angleBetween
01171   
01172   angleBetween: other=C3DThing -> CFrogNum |
01173     px=CFrogNum
01174     py=CFrogNum
01175     ox=CFrogNum
01176     oy=CFrogNum
01177     r=CFrogNum
01178   |
01179     ox _ other ->x - x .
01180     oy _ other ->y - y .
01181     px _ angle cos * 100 .
01182     py _ angle sin * 100 .
01183     r _ (
01184         ((px * ox) + (py * oy ) ) / 
01185          (((( px * px ) + ( py * py )) sqrt 
01186            * (( ox * ox )+ ( oy * oy )) sqrt ) + .1 )
01187       ) arccos .
01188     ^ r
01189 
01190                                    assign_id
01191   
01192   assignID -> CFrogNum
01193   |
01194     id=CFrogNum
01195     ids=CFrogArray
01196     cnt=CFrogNum
01197   |
01198     #world -> is_server ifTrue: [
01199       'TODO less dumb method of doing this'.
01200       (#next_id hasClass: CFrogNum) ifTrue: [
01201         #world->free_ids size = 0 ifTrue: [
01202           #next_id _ #next_id + 1 .
01203           server_id _ #next_id .
01204           ^ #next_id
01205         ] ifFalse: [
01206           id _ #world->free_ids last .
01207           #world->free_ids remove: id .
01208           server_id _ id .
01209           ^ id
01210         ] .
01211       ] ifFalse: [
01212         server_id _ 1 .
01213         #next_id _ 1 .
01214         ^ 1 .
01215       ] .
01216     ] .
01217     ^ 0 .
01218 
01219                                  beforeRestore
01220   
01221   
01222 
01223                                     bestHit
01224   
01225   bestTargetAtAngle: angle=CFrogNum ->C3DThing |
01226     best_thing=C3DThing
01227     best_angle=CFrogNum
01228     from_angle=CFrogNum
01229     canidates=CFrogArray
01230   |
01231     canidates _ #world thingsInDist: 128 * 32 atAngle: angle fromThing: self .
01232     best_angle _ 6.24 .
01233     best_thing _ 0 .
01234     canidates do: [:t=C3DThing |
01235   'can' show .
01236   t show .
01237       ((self canSeeThing: t) and: (self ~= t and: t->health > 0. )) ifTrue: [
01238   'see' show.
01239   self show.
01240   t show .
01241         from_angle _ (self angleFromThing: t facingAngle: angle ) .
01242         from_angle < best_angle ifTrue: [
01243           best_angle _ from_angle .
01244           best_thing _ t .
01245         ]
01246       ]
01247     ] .
01248   'best' show .
01249   best_angle show .
01250     best_angle < (3.14 / 2 / 8) ifTrue: [
01251       ^ best_thing .
01252     ] .
01253     ^ 0
01254   
01255 
01256                                      damage
01257   
01258   damage: amt=CFrogNum ->* ||
01259   'damage' .
01260     health _ health - amt .
01261 
01262                                       die
01263   
01264   die ->*
01265   |
01266     w=C3DWorldManager
01267     all=CFrogNum
01268   | 
01269     w _ #world .
01270     self dropItem .
01271     activate_tag ifTrue: [
01272       'Check if all enemies with the tag poo poo are dead' .
01273       'If so,be sure to activate all doors with the right tag' .
01274       all _ 1 .
01275       no_update _ 1 .
01276       w->things do:[:t=C3DThing|
01277         (t hasClass: C3DThing) ifTrue: [
01278           t->activate_tag = activate_tag ifTrue: [
01279             t->health <= 0 ifFalse: [ all _ 0 . ]
01280           ]
01281         ] .
01282       ] .
01283       all ifTrue: [
01284         w->doors do:[:d=CDoor|
01285           d activateByTag: activate_tag .
01286         ] .
01287       ] .
01288     ] .
01289 
01290                                     dropItem
01291   
01292   dropItem -> CFrogNum
01293   |
01294   item*
01295   |
01296     (drop_thing hasClass: CFrogClass) ifTrue: [
01297       item _ drop_thing new .
01298       item->x _ x .
01299       item->y _ y .
01300       item->z _ z .
01301       ^ 1
01302     ] .
01303     ^ 0 .
01304 
01305                                     getAngle
01306   
01307   getAngle->CFrogNum ||
01308     ^ angle
01309 
01310                                    getHealth
01311   
01312   getHealth->CFrogNum || ^ health
01313 
01314                                     getName
01315   
01316   getName ->CFrogStr ||
01317     ^ name
01318 
01319                                    isOverEdge
01320   
01321   isOverEdge ->CFrogNum
01322   |
01323   |
01324     1 to: 3 do: [:d=CFrogNum|
01325       (#world getTileAtX: x / 128 atY: y / 128 atZ: z - d) ~= 0 ifTrue: [
01326         ^ 0.
01327       ].
01328     ] .
01329     ^ 1 
01330 
01331                                lookForHealTarget
01332   
01333   lookForHealTarget ->C3DThing
01334   |
01335     things=CFrogArray
01336     p=CPlayer
01337   |
01338     p _ #world getPlayer .
01339     things _ #world getThingsInRadiusFromX: x fromY: y withRadius: 16 * 128 .
01340     things do: [:t=C3DThing |
01341       'Make sure not a door'.
01342       ((t hasClass: C3DThing) and: p ~= t) ifTrue: [
01343         ((t hasClass: CRocket) not and: t->health <= 0. ) ifTrue: [
01344           ((self canSeeThing: t) and: t ~= self) ifTrue: [
01345             ^ t
01346           ] .
01347         ]
01348       ].
01349     ] .
01350     ^ 0.
01351 
01352                                  lookForTarget
01353   
01354   lookForTarget -> C3DThing
01355   |
01356   |
01357     (#world getThingsInRadiusFromX: x fromY: y withRadius: 16 * 128 ) do:[:t=C3DThing|
01358       (t hasClass: CPlayer) ifTrue: [
01359         ((self canSeeThing: t) and: t->health > 0) ifTrue: [
01360           ^ t
01361         ] .
01362       ]
01363     ] .
01364     ^ 0 .
01365 
01366                                 moveGoesOverEdge
01367   
01368   moveGoesOverEdge: dist=CFrogNum atAngle: a=CFrogNum ->CFrogNum
01369   |
01370     xx=CFrogNum
01371     yy=CFrogNum
01372     zz=CFrogNum
01373     tile=CFrogNum
01374   |
01375     dist _  (3.5 * dist) + template->radius.
01376     xx _ x + (dist * a cos) .
01377     yy _ y + (dist * a sin) .
01378   
01379     tile _ #world getTileAtX: xx / 128  atY: yy / 128 atZ: z - 1 .
01380     tile ~= 0 ifTrue: [
01381       tile _ #world getTileAtX: xx / 128  atY: yy / 128 atZ: z - 2 .
01382   'Hole in ground ' .
01383       ^ tile = 0 .
01384     ] .
01385     ^ 0 
01386 
01387                                newChaseDirection
01388   
01389   newChaseDirection: dist=CFrogNum withTarget: target=C3DThing ->CFrogNum
01390   |
01391     rand=CFrogRandom
01392     dir=CFrogNum
01393     hit_wall=CFrogNum
01394     omx2=CFrogNum
01395     omy2=CFrogNum
01396     in_rad=CFrogArray
01397   |
01398     rand _ CFrogRandom new .
01399     omx2 _ momx2 .
01400     omy2 _ momy2 .
01401     angle _ self pathFinderAngleTowardsThing: target withJump: 1.5 .
01402     (target hasClass: C3DThing ) ifTrue: [
01403       hit_wall _ self move: dist  atAngle: angle .
01404       ((self moveGoesOverEdge: dist atAngle: angle) not and: hit_wall not) ifTrue: [
01405         momx2 _ omx2 .
01406         momy2 _ omy2 .
01407         ^ angle .
01408       ] .
01409     ] .
01410     momx2 _ omx2 .
01411     momy2 _ omy2 .
01412     self newDirection: dist .
01413     momx2 _ omx2 .
01414     momy2 _ omy2 .
01415     ^ angle .
01416 
01417                                  newdirection2
01418   
01419   newDirection: dist=CFrogNum ->CFrogNum
01420   |
01421     rand=CFrogRandom 
01422     dir=CFrogNum
01423     hit_wall=CFrogNum
01424     oldmx2=CFrogNum
01425     oldmy2=CFrogNum
01426   |
01427     rand _ CFrogRandom new .
01428     (rand next < .5) ifTrue: [
01429       dir _ -1 .
01430     ] ifFalse: [
01431       dir _ 1 .
01432     ] .
01433   
01434     oldmx2 _ momx2 .
01435     oldmy2 _ momy2 .
01436     angle _ angle + 3.14 .
01437   
01438     0 to: 8 do: [:inc=CFrogNum|
01439       angle _ angle + (dir * (3.14 * 2 / 8 )).
01440   'Nroot here DUMB hack' .
01441   'momx/y2  is the move mommentum,reset to avoid unintented side effecvts '.
01442       momx2 _ oldmx2 .
01443       momy2 _ oldmy2 .
01444       hit_wall _ self move: dist  withAngle: angle . 
01445       ((self moveGoesOverEdge: dist atAngle: angle) not and: hit_wall not) ifTrue: [
01446   'See above note'.
01447         momx2 _ oldmx2 .
01448         momy2 _ oldmy2 .
01449         ^ angle .
01450       ] .
01451     ].
01452   
01453     'No where to go ' .
01454     momx2 _ oldmx2 .
01455     momy2 _ oldmy2 .
01456   
01457 
01458                                     onGround
01459   
01460   
01461 
01462                                  rayHitsTarget
01463   
01464   screenRayHitsTarget: t=C3DThing atAngle: a=CFrogNum 
01465     ->CFrogNum
01466   |
01467     dist=CFrogNum
01468     dist_scale=CFrogNum
01469     tolerance=CFrogNum
01470   |
01471     (self canSeeThing: t ) ifFalse: [
01472       ^ 0
01473     ] .
01474     'See 3D.HC' .
01475     dist_scale _ 128 * 480 .
01476     dist _ ( (x - t ->x ) squared + (y - t ->y ) squared ) sqrt .
01477     dist _ dist_scale / ( dist + .1 ) .
01478     tolerance _ ( 3.14 / 4 / 640 ) * dist.
01479     (self angleBetween: t) < tolerance ifTrue: [
01480       ^ 1
01481     ] .
01482     ^ 0. 
01483 
01484                               rayHitsTargetAutoAim
01485   
01486   angleFromThing: t=C3DThing
01487     facingAngle: a=C3DThing
01488     -> CFrogNum
01489   | 
01490     xx=CFrogNum
01491     yy=CFrogNum 
01492     dist=C3DThing
01493     dist_scale=C3DThing
01494     tolerance=C3DThing
01495   |
01496     'See 3D.HC' .
01497     xx _ t->x - self->x .
01498     yy _ t->y - self->y .
01499     a _ ((xx arg: yy ) - a) rem: 6.24 .
01500     a > 3.14 ifTrue: [
01501       a _ 6.24 - a 
01502     ] .
01503     ^ a abs .
01504 
01505                                   sendToStream
01506   
01507   sendToStream: s=CNetStream ->*
01508   |
01509   |
01510     s remoteMethodCall: 'recv3DThing:' withArguments: #(
01511      #(
01512        (x)
01513        (y)
01514        (z)
01515        (momx)
01516        (momy)
01517        (momz)
01518        (angle)
01519        (health)
01520        (template->name)
01521        (animation_start_tS)
01522        (animation_no_repeat)
01523       )
01524     ) .
01525 
01526                                     setAngle
01527   
01528   setAngle: a =CFrogNum ->* ||
01529     angle _ a .
01530 
01531                                     setName
01532   
01533   setName: n=CFrogStr ->*||
01534     name _ n copy 
01535 
01536                               swimAtAngleAtAngle2
01537   
01538   swim: d=CFrogNum atAngle: a=CFrogNum atAngle2: a2=CFrogNum
01539     ->CFrogNum
01540   |
01541     xx=CFrogNum
01542     yy=CFrogNum
01543     zz=CFrogNum
01544     xx2=CFrogNum
01545     yy2=CFrogNum
01546     zz2=CFrogNum
01547   |
01548     xx _ d .
01549     yy _ 0 .
01550     zz _ 0 .
01551   
01552    'Rotate around y axis ' .
01553     xx2 _ (xx * a2 cos) + (zz * a2 sin ).
01554     yy2 _ yy .
01555     zz2 _ (xx * a2 sin) - (zz * a2 cos ).
01556   
01557     'Rotate around z axis ' .
01558     xx _ xx2 . 
01559     yy _ yy2 . 
01560     zz _ zz2 . 
01561   
01562     xx2  _ (xx * a cos) - (yy * a sin) . 
01563     yy2  _ (xx * a sin) + (yy * a cos) .
01564     zz2 _ zz .
01565   
01566     momz2 _ momz2 +(zz2/ 128)  .
01567     ^ self move: (xx2 squared + yy2 squared ) sqrt atAngle: (xx2 arg: yy2) . 
01568 
01569                                      wander
01570   
01571   wander:speed=CFrogNum ->*
01572   |
01573     rand=CFrogRandom
01574   |
01575     momx2 _ 0 .
01576     momy2 _ 0 .
01577     ((self move: speed atAngle: angle) or: hit_thing) ifTrue: [
01578       'Hit wall' .
01579       self newDirection: speed .
01580       self move: speed atAngle: angle .
01581     ] ifFalse: [
01582       rand _ CFrogRandom new.
01583       rand next < (.1 /10 ) ifTrue: [
01584         self newDirection: speed .     
01585       ] .
01586     ] .
01587     hit_thing _ 0 .
01588 
01589                                    wanderFly
01590   
01591   wanderFly: speed=CFrogNum withTarget: target=C3DThing ->* |
01592     w=C3DWorldManager
01593     f=CFrogNum
01594     hit_wall=CFrogNum
01595     rand=CFrogRandom
01596   |
01597     momx2 _ 0 .
01598     momy2 _ 0 .
01599     hit_thing ifTrue: [
01600       self newDirection: speed . 
01601       self move: speed atAngle: angle .
01602       hit_thing _ 0 .
01603       ^ 1 .
01604     ] .
01605     self newChaseDirection: speed withTarget: target .
01606     momz _ (( 1.5 + target->z) -z) * .1 .
01607   'Dont go too fast up or down'.
01608     momz > .5 ifTrue: [ momz _ .5 ].
01609     momz < .5 negated ifTrue: [ momz _ .5 negated ].
01610   
01611     self move: speed atAngle: angle .
01612     ^ 1 .
01613     
01614 
01615                                  wanderWithJump
01616   
01617   wander: dist=CFrogNum
01618     withJumpVelocity: jmp_velo=CFrogNum
01619     withTarget: target=C3DThing ->*
01620   |
01621     rand=CFrogRandom
01622     hit_wall=CFrogNum
01623   |
01624     momx2 _ 0 .
01625     momy2 _ 0 .
01626     hit_thing ifTrue: [
01627       hit_thing _ 0 .
01628       self newDirection: dist .
01629       ^ (self move: dist atAngle: angle ) not.
01630     ].
01631     (self moveGoesOverEdge: dist atAngle: angle) not ifTrue: [
01632       hit_wall _ self move: dist atAngle: angle .
01633       (hit_wall and: self isOnGround ) ifTrue: [
01634         'Check if 1 block jump'.
01635         (#world getTileAtX: (x + (128 * angle cos ))/ 128 atY: (y + (128 * angle sin))/ 128 atZ: z + 1) = 0 ifTrue: [
01636           momz _ jmp_velo .
01637           ^ 1 .
01638         ] .
01639         ^ 0 .
01640       ] . 
01641       self newChaseDirection: dist withTarget: target .
01642     ] ifFalse: [
01643   ^ 0 .
01644       self isOnGround ifTrue: [
01645         'Check if 1 block depress' .
01646         (#world getTileAtX: (x + (128 * angle cos ))/ 128 atY: (y + (128 * angle sin))/ 128  atZ: z - 1) = 0 ifTrue: [
01647           'Just jump into pit'.
01648           momz _ jmp_velo .
01649           ^ 1 .
01650         ] .
01651       ] .
01652       self newChaseDirection: dist withTarget: target .
01653       ^ 0.
01654     ] .
01655     
01656   
01657     ^ 1 . 
01658 
01659                                       xPos
01660   
01661   xPos->CFrogNum | |
01662     ^ x
01663 
01664                                       zPos
01665   
01666   zPos ->CFrogNum|| ^  z
01667 
01668                                   CONSTRUCTOR
01669   
01670   init | |
01671     radius _ 128 / 3 .
01672     ^ self
01673   
01674 
01675                                     SETNAME
01676   
01677   setName:n=CFrogStr ->* ||
01678     name _ n copy .
01679 
01680                                   sendToStream
01681   
01682   sendToStream: s=CNetStream
01683   ->*
01684   |
01685   |
01686     s remoteCallMethod: 'recv3DThingTemplate:' withArguments: #(
01687       #(
01688         (name)
01689         (front->name)
01690         (side->name)
01691         (back->name)
01692         (front asString)
01693         (side asString)
01694         (back asString)
01695       )
01696     ) .
01697   
01698 
01699                                     setBack
01700   
01701   setBack: i*
01702   ->*
01703   |
01704   |
01705     (i hasClass: CFrogStr) ifTrue: [
01706      i _ CFrogImg get: i 
01707     ] .
01708     back _ i  .
01709     self save 
01710 
01711                                     setFront
01712   
01713   setFront: i*
01714   ->*
01715   |
01716   |
01717     (i hasClass: CFrogStr) ifTrue: [
01718      i _ CFrogImg get: i 
01719     ] .
01720     front _ i.
01721     self save .
01722 
01723                                     setside
01724   
01725   setSide: i*
01726   ->*
01727   |
01728   |
01729     (i hasClass: CFrogStr) ifTrue: [
01730      i _ CFrogImg get: i 
01731     ] .
01732   
01733     side _ i .
01734     self save
01735 
01736                                 updateProperties
01737   
01738   sendProperties ->*
01739   |
01740     w=C3DWorldManager
01741     c=C3DWorldClient
01742     msg=CFrogArray
01743   |
01744   
01745     msg _ #(
01746       (name)
01747       (front->name)
01748       (side->name)
01749       (back->name)
01750       (front asString)
01751       (side asString)
01752       (back asString)
01753     ).
01754   
01755   
01756     w _ #world .
01757     w->is_client ifTrue: [
01758       c _ #client .
01759       c sendMessage: msg  withType: 'TmpU' .
01760     ] .
01761     w->is_server ifTrue: [
01762       w->clients do: [:c=C3DWorldClient|
01763         c sendMessage: msg withType: 'TmpU'.
01764       ] .
01765     ] .
01766 
01767                                   CONSTRUCTOR
01768   
01769   initFromStream:s=CNetStream ->C3DWorldClient 
01770   |
01771     recur=CFrogBlock
01772     now=CFrogNum
01773   |
01774     sock _ CAsyncStream newFromStream s .
01775     last_response_tS _ CFrogTime now asSeconds .
01776     
01777     recur _ [
01778       sock readU32WithCallback:[:w* :cnt=CFrogNum|
01779        last_response_tS _ CFrogTime now asSeconds .
01780        sock readBytes: cnt withCallback: [:w* :buf=CFrogStr|
01781           self handleMessage: buf .
01782           'Re-arm callbackcs' .
01783           recur value .
01784         ].
01785       ] .
01786     ]
01787      recur value .
01788     ^ self
01789   
01790 
01791                                    armUpdates
01792   
01793   armUpdates ->*
01794   |
01795     now=CFrogNum
01796   |
01797     update_thread _ CFrogThread spawn: [
01798       [sock->closed] whileFalse: [
01799         (update hasClass: CFrogBlock) ifTrue: [
01800           CFrogTime now asSeconds >= next_update_tS ifTrue: [
01801             0 to: sock->ops size do: [
01802               update value .
01803             ] .
01804             'Approxmate next update based on last response time' .
01805             now _ CFrogTime now asSeconds .
01806             next_update_tS _ (((now  - last_response_tS) * 1.5 max: 1 / 10) 
01807               min: 1.5) + now  .
01808             CFrogThread sleep: next_update_tS - now .
01809           ] .
01810         ] .
01811         CFrogThread yield .
01812       ] .
01813     ].
01814   
01815 
01816                                  handleMessage
01817   
01818   handleMessage:m=CFrogStr ->*
01819   |
01820   tile=CTileTemplate
01821   texture=CFrogImg
01822   type=CFrogStr
01823   array*
01824   tmp*
01825   |
01826     m size <5 ifTrue: [
01827      'Malformed server response ' show .
01828      m show .
01829      'Closing connection ' show. 
01830      sock close .
01831      ^ 0 
01832     ].
01833     type _ m copyFrom: 0 to: 4 .
01834     array _ (m copyFrom: 5 to: m size ) restoreThing .
01835   
01836     'msg type ' show .
01837     type show .
01838     array size show .
01839    
01840     type = 'Wrld' ifTrue: [
01841       #world restoreBlocksFromString: array first
01842         withWidth: (array at: 1)
01843         withHeight: (array at: 2) .
01844       #world ->things _ #(). 
01845       #world initGrid .
01846       #world ->is_client _ 1 .
01847       player _ CPlayer new .
01848       #player _ player .
01849     ] .
01850     type = 'PSpn' ifTrue: [
01851       'Server sets the player position(Player spawns)' .
01852       player ->x _ array first .
01853       player ->y _ array at: 1 .
01854       player ->z _ array at: 2 .
01855       player ->angle _ array at: 3 .
01856     ] .
01857     type = 'PDmg' ifTrue: [
01858       'Server damges Player' .
01859       player damage: array first .
01860     ] .
01861     type ='SThg' ifTrue: [
01862       'Send Things' .
01863       m show .
01864       self receiveThings: array .
01865     ].
01866     type = 'PBlk' ifTrue: [
01867       #world setTile: array first 
01868         atX: (array at: 1)
01869         atY: (array at: 2)
01870         atZ: (array at: 3)
01871     ] .
01872     type = 'EBlC' ifTrue: [
01873       tile _ #world->tile_templates at: (array at:2) .
01874       texture _ CFrogImg get: array first .
01875       texture setGraphicsFromString: (array at:1) .
01876       tile setCeil: texture->name .
01877     ].
01878     type = 'EBlW' ifTrue: [
01879       tile _ #world->tile_templates at: (array at:2) .
01880       texture _ CFrogImg get: array first .
01881       texture setGraphicsFromString: (array at:1) .
01882       tile setWall: texture->name .
01883     ].
01884     type = 'EBlF' ifTrue: [
01885       tile _ #world->tile_templates at: (array at:2) .
01886       texture _ CFrogImg get: array first .
01887       texture setGraphicsFromString: (array at:1) .
01888       tile setFloor: texture->name .
01889     ].
01890     type = 'Line' ifTrue: [
01891       #world -> lines _ array .
01892     ] .
01893     type = 'PkUp' ifTrue: [
01894       tmp _ array first .
01895       tmp addToPlayer: player .
01896     ] .
01897     type = 'NPrt' ifTrue: [
01898       #world newParticleAtX: (array at: 0)
01899         atY: (array at: 1)
01900         atZ: (array at: 2)
01901         withSpread: (array at: 3)
01902         withColor: (array at: 4)
01903         withSplatLump: (array at: 5)
01904     ] .
01905 
01906                                       new
01907   
01908   init
01909   ->*
01910   |
01911   |
01912     ^ self
01913 
01914                                 newConnectionTo
01915   
01916   connectToServer: addr=CFrogStr atPort: p=CFrogNum ->*
01917   |
01918     recur=CFrogBlock
01919   |
01920     sock _ CAsyncStream newConnectionTo: addr atPort : p .
01921     recur _ [ 
01922   'recur 'show .
01923       sock readU32WithCallback: [:sock* :cnt=CFrogNum|
01924         last_response_tS _ CFrogTime now asSeconds .
01925         sock readBytes: cnt withCallback: [:sock* :buf=CFrogStr|
01926           last_ping_tS _ CFrogTime asSeconds .
01927           self handleMessage: buf.
01928           'Retrigger the callback' .
01929           recur value .
01930         ] .
01931       ] .
01932     ] .
01933     update _ [
01934       self sendPlayerMovement.
01935     ] .
01936     next_update_tS _ CFrogTime now asSeconds .
01937     #client _ self .
01938     self armUpdates .
01939     recur value .
01940     
01941 
01942                                  receiveThings
01943   
01944   receiveThings: data* ->*
01945   |
01946     have=CFrogArray
01947     w=C3DWorldManager
01948     me=CPlayer
01949     thing=C3DThing
01950     now=CFrogNum
01951     use_raw=CFrogNum
01952     new=CFrogArray
01953   |
01954     w _ #world .
01955     me _ w getPlayer .
01956     w->things do:[:t*|
01957       t ~= me ifTrue: [
01958         w removeFromGrid: t .
01959       ]
01960     ] .
01961   
01962   'data size showq '.
01963     data size show .
01964   
01965   
01966     now  _ CFrogTime now asSeconds .
01967   
01968     use_raw _ 0 .
01969     (now - #old_interpolation_tS) > 1.5 ifTrue: [
01970       #old_interpolation_tS _ now .
01971       use_raw _ 1 .
01972     ] .
01973   
01974     new _ #() .
01975   
01976     'Data isnt the whole picture'.
01977     'It has format ' .
01978     'Player is not included in things' .
01979     data do:[:entry=CFrogArray|
01980       thing _ (entry at:4) basicNew .
01981   
01982       thing->interpolate_start_tS  _ #old_interpolation_tS .
01983       thing->interpolate_end_tS  _ now .
01984   
01985       thing->server_old_x _ entry at: 6 . 
01986       thing->server_old_y _ entry at: 7 .  
01987       thing->server_old_z _ entry at: 8 .
01988       thing->server_new_x _ entry at: 0 . 
01989       thing->server_new_y _ entry at: 1 . 
01990       thing->server_new_z _ entry at: 2 . 
01991     
01992       thing->x _ thing->server_old_x .
01993       thing->y _ thing->server_old_y .
01994       thing->z _ thing->server_old_z .
01995       
01996       thing->angle _ entry at: 3 .
01997       thing->template _ #world getThingTemplate: (entry at:5) .
01998   
01999       thing->health _ entry at: 9 .
02000       thing->animation_no_repeat _ entry at: 10 .
02001       thing->animation_start_tS _ (entry at: 11) + now .
02002       thing->server_id _ entry at: 12 .
02003       thing->activate_tag _ entry at: 13 .
02004   
02005       w updateThingPos: thing .
02006   
02007       new add: thing .
02008     ] .
02009   
02010     new add: player .
02011     w->things _ new .
02012   
02013     #old_interpolation_tS _  now .
02014     
02015 
02016                               sendEditCeilForBlock
02017   
02018   sendEditCeil: img=CFrogImg forBlock: tile=CFrogNum ->*
02019   |
02020   |
02021    self sendMessage:
02022     #(
02023       img->name 
02024       (img asString )
02025       tile 
02026     ) 
02027     withType: 'EBlC' . 
02028 
02029                              sendEditFloorForBlock
02030   
02031   sendEditFloor: img=CFrogImg forBlock: tile=CFrogNum ->*
02032   |
02033   |
02034    self sendMessage:
02035     #(
02036       img->name 
02037       (img asString )
02038       tile 
02039     ) 
02040     withType: 'EBlF' . 
02041 
02042                                   sendEditPoo
02043   
02044   sendEditWall: img=CFrogImg forBlock: tile=CFrogNum ->*
02045   |
02046   |
02047    self sendMessage:
02048     #(
02049       img->name 
02050       (img asString )
02051       tile 
02052     ) 
02053     withType: 'EBlW' . 
02054 
02055                               sendMessageWithType
02056   
02057   sendMessage: m* withType: t=CFrogStr ->*
02058   |
02059     fin=CFrogStr
02060   | 
02061     fin _ t , '.' , m saveThing .
02062     sock->sock sendI32: fin size .
02063     sock write: fin  .
02064 
02065                                sendPickupToClient
02066   
02067   sendPickupToClient: p=CPickup ->*
02068   | 
02069   |
02070     self sendMessage: #(
02071       p
02072     ) withType: 'PkUp' .
02073 
02074                                     sendPiss
02075   
02076   sendPiss ->*
02077   |
02078   | 
02079   'PIIS222' show .
02080     self sendMessage: #(
02081       player -> angle
02082       player -> angle2
02083     ) withType: 'Piss' .
02084 
02085                                  sendPlaceBlock
02086   
02087   sendPlaceBlock: tile=CFrogNum atX: x* atY: y* atZ: z*
02088   ->*
02089   |
02090   |
02091     self sendMessage: #(
02092       (tile)
02093       (x)
02094       (y)
02095       (z)
02096     ) withType: 'PBlk' . 
02097 
02098                                  sendPlaceDoor
02099   
02100   sendPlaceDoor: d=CDoor ->*
02101   ||
02102     self sendMessage: #(
02103        d
02104     ) withType: 'PDor' .
02105 
02106                                  sendPlaceThing
02107   
02108   sendPlaceThing: t=CFrogClass atX: x* atY: y* atZ: z*
02109   withActivateTag: tag=CFrogNum
02110   ->*
02111   |
02112   |
02113     self sendMessage: #(
02114         (t name)
02115         (x)
02116         (y)
02117         (z)
02118         (tag)
02119       )
02120       withType: 'PThg' .
02121 
02122                             sendPlayerAttackToServer
02123   
02124   sendAttackOfThing: t=C3DThing withDamage: dmg=CFrogNum
02125   ->* 
02126   |
02127   |
02128     self sendMessage: #(
02129       (t->x)
02130       (t->y)
02131       (t->z)
02132       (dmg)
02133       t->server_id
02134       (t class name)
02135     ) withType: 'Damg' .
02136    
02137 
02138                                sendPlayerMovement
02139   
02140   sendPlayerMovement ->*
02141   |
02142   |
02143     'send p ' show .
02144     player show .
02145     self sendMessage: #(
02146       (player->x)
02147       (player->y)
02148       (player->z)
02149       (player->angle)
02150     )
02151     withType:'PMov'.
02152 
02153                                  sendProjectile
02154   
02155   shootProjectile: type=CFrogClass
02156    atX:  x*
02157    atY: y*
02158    atZ: z*
02159    withMomX: mx*
02160    withMomY: my*
02161    withMomZ: mz*
02162   ->*
02163   |
02164   |
02165     self sendMessage: #(
02166       (type)
02167       (x)
02168       (y)
02169       (z)
02170       (mx)
02171       (my)
02172       (mz)
02173     ) withType: 'Proj' .
02174 
02175                                   ADDNEWTHING
02176   
02177   addNewThingFromClass: st_class* atX: x=CFrogNum atY: y=CFrogNum ->* |new=C3DThing|
02178     new _ st_class new .
02179     new isNil ifTrue: [
02180       ^ new
02181     ] .
02182     new ->x _ x .
02183     new ->y _ y .
02184     self addThing: new .
02185     ^ new
02186 
02187                                     ADDTHING
02188   
02189   addThing: thing=C3DThing ->* |
02190       hash=CFrogNum
02191       names=CFrogArray
02192       first=CFrogStr
02193       last=CFrogStr
02194   |
02195   '() prevents strings from being meged' .
02196     names _ #(
02197        ('Asshole')
02198        ('Buttman')
02199        ('Beavis')
02200        ('Coochis')
02201        ('Dick')
02202        ('Elbrus')
02203        ('Fred')
02204        ('Gilber')
02205        ('Grover')
02206        ('Hilbert')
02207        ('Incestman')
02208        ('Jeffery')
02209        ('Kilroy')
02210        ('Lovin')
02211        ('Mo')
02212        ('Meanbean')
02213        ('Nugget')
02214        ('Ovulary')
02215        ('Penis')
02216        ('Quiin')
02217        ('21')
02218        ('Septicus')
02219        ('Tumor')
02220        ('Truffle')
02221        ('Uppy')
02222        ('Uranus')
02223        ('Venus')
02224        ('Wigglyston')
02225        ('Retard')
02226        ('Ben')
02227     ) .
02228     first _ names at: (thing ->x * 123.456  rem:  names size ) .
02229     names _ #(
02230       ('Assholeingston')
02231       ('Ballsackingston')
02232       ('B')
02233       ('Bungisman')
02234       ('Clitoris')
02235       ('Dingleberry')
02236       ('Dickens')
02237       ('Elseworth')
02238       ('Fucks')
02239       ('Fatload')
02240       ('Gigglyman')
02241       ('Hellhole')
02242       ('Incestman')
02243       ('Jiggis')
02244       ('Kilroy')
02245       ('Loverman')
02246       ('Mo')
02247       ('Nuggith')
02248       ('Oooyeeh')
02249       ('Penisman')
02250       ('Pepperhead')
02251       ('Sexyman')
02252       ('Saggage')
02253       ('Timbo')
02254       ('Wuggis')
02255       ('Z80')
02256     ) .
02257     last _ names at: (thing ->y * 567.89  rem: names size ) .
02258     thing setName: first , ' ' , last .
02259     (things includes: thing) not ifTrue: [
02260       things add: thing .
02261     ] .
02262   
02263     first show .
02264     thing->chat_bot _ self getQuestChatBot: thing->chat_bot_name .
02265     self updateThingPos: thing .
02266   
02267     is_server ifTrue: [
02268       thing assignID .
02269     ]
02270 
02271                                 ADDTHINGTEMPLATE
02272   
02273   addThingTemplate: t=C3DThingTemplate withName: name=CFrogStr ||
02274     t setName: name .
02275     thing_templates at: name put: t
02276 
02277                                   CONSTRUCTOR
02278   
02279   init | gx=CFrogNum gy=CFrogNum col=CFrogArray |
02280     #world _ self .
02281     day_night _ CDayNight new .
02282     wall_stains _ #() .
02283     floor_stains _ #() .
02284     things _ #() .
02285     grid _ # () .
02286     gravity _ 3 / 30 .
02287     tile_templates _ #() .
02288   'Lookup table '.
02289     0 to: 256 do: [
02290       tile_templates add: 0 .
02291     ].
02292     thing_templates _ CFrogDictionary new .
02293     self initGrid .
02294   
02295     doors _ #() .
02296     clients _ #().
02297     lines _ #() .
02298     lights _ #() .
02299   
02300     level _ CLevel new .
02301     level->display_name _ 'Untitled mofufckin level'.
02302     ^ self
02303   
02304 
02305                                    GETPLAYER
02306   
02307   getPlayer -> CPlayer | |
02308     (player hasClass: CPlayer) ifFalse: [
02309       things do : [:t* |
02310         (t hasClass: CPlayer) ifTrue: [player _ t ] .
02311       ] .
02312     ].
02313     ^ player 
02314 
02315                                 GETTHINGTEMPLATE
02316   
02317   getThingTemplate: name=CFrogStr ->C3DThingTemplate ||
02318     'Template' show .
02319     name show .
02320     (thing_templates at: name) show .
02321     ^ thing_templates at: name .
02322   
02323 
02324                                     GRAVITY
02325   
02326   gravity ->CFrogNum ||
02327     ^ gravity
02328 
02329                                      UPDATE
02330   
02331   update ->* |
02332     p=CPlayer
02333     now=CFrogNum
02334     dist=CFrogNum
02335     simulation_dist=CFrogNum
02336     pickups=CFrogArray
02337     tmp=CFrogArray
02338     ps=CPissStream
02339     lnb=CLightningBolt
02340     line=C3DLine
02341     line2=C3DLine
02342   |
02343     is_paused ifTrue: [
02344       ^0 
02345     ] .
02346     p _ self getPlayer .
02347   
02348     is_client ifTrue: [
02349      'Let server do updating '.
02350       ^ 1 .
02351     ].
02352     self handlePowerups .
02353     now _ CFrogTime now asSeconds .
02354     ( last_update + 1 / 10. ) > now ifTrue: [
02355       ^ 0
02356     ] .
02357     simulation_dist _ 24 * 128 .
02358     clients do: [:c=C3DWorldClient |
02359       self sendThingsToClient: c .
02360     ].
02361   
02362     last_update _ now .
02363     things do: [:t* |
02364       t->server_old_x _ t->x .
02365       t->server_old_y _ t->y .
02366       t->server_old_z _ t->z .
02367       t->no_update ifFalse: [
02368         t->momx2 _ 0 .
02369         t->momy2 _ 0 .
02370         t->momz2 _ 0 .
02371         t update
02372       ] .
02373     ].
02374   
02375     'UI and stuf' .
02376     (#hand_item hasClass: CHandItem) ifTrue: [
02377       #hand_item animate
02378     ] .
02379   
02380     self updateLines .
02381     clients do: [:c=C3DWorldClient|
02382       self sendLinesToClient: c .
02383     ] .
02384   
02385     doors do: [:d=CDoor|
02386       d update 
02387     ] .
02388 
02389                                    addClient
02390   
02391   addClient: sock=CNetStream ->C3DWorldClient
02392   |
02393     c=C3DWorldClient
02394     p=CPlayer
02395     best=CFrogNum
02396     world_str=CFrogStr 
02397     buf=CFrogStr
02398     recur=CFrogBlock
02399   |
02400     c _ C3DWorldClient basicNew .
02401     c -> player _ CPlayer new .
02402     'TODO place the player in a good spawn zone' .
02403     p _ c->player .
02404     p->x _ self width / 2 * 128 + 64 . 
02405     p->y _ self height / 2 * 128 + 64 .
02406     p->z _ 128 .
02407     best _ -127 .
02408     -127 to: 127 by: 1 do: [:h=CFrogNum |
02409       (self getTileAtX: p->x / 128 atY: p->y / 128 atZ: h) ifFalse: [
02410   'Check for ground ' .
02411         (self getTileAtX: p->x / 128 atY: p->y / 128 atZ: h - 1 ) ifTrue: [
02412           p->z _ h .
02413           best _ p->z max: best .
02414         ] .
02415       ]. 
02416     ] . 
02417     best = -127 ifTrue: [
02418     'Wut,nowhere to stand so place at top of world' .
02419       p->z _ 128 . 
02420     ] ifFalse: [
02421       p->z _ best .
02422     ] .
02423     self removeFromGrid: c->player.
02424     self updateThingPos: c->player.
02425   
02426     c->last_ping_tS _ CFrogTime now asSeconds .
02427     c->sock _ CAsyncStream newFromStream: sock .
02428   
02429     world_str _ blocks_string .
02430     c sendMessage: #((world_str) (blocks_width) (blocks_height))  withType: 'Wrld' .
02431     c sendMessage: #(
02432       (p->x)
02433       (p->y)
02434       (p->z)
02435       (p->angle)
02436     ) withType: 'PSpn' .
02437   
02438     c->last_response_tS _ CFrogTime now asSeconds .
02439     recur _ [
02440       c->sock readU32WithCallback: [:sock* :cnt=CFrogNum|
02441         c->last_response_tS _ CFrogTime now asSeconds.
02442         c->sock readBytes: cnt withCallback: [:sock* :buf=CFrogStr|
02443           c->last_ping_tS _ CFrogTime now asSeconds .
02444           self handleMessage: buf forClient: c .
02445           'Re-enabled callback' .
02446           recur value 
02447         ] .
02448       ] .
02449     ] . 
02450   
02451     clients add: c .
02452     c->update _ [
02453     ].
02454     c armUpdates .
02455     recur value .
02456 
02457                                     addDoor
02458   
02459   addDoor:d=CDoor->* ||
02460     doors add: d .
02461     ((doors_grid at: d->x / 16 )
02462       at: d->y / 16 ) add: d
02463 
02464                                  addFloorStain
02465   
02466   addFloorStain: s=CFloorStain ->*
02467   |
02468   |
02469    'TODO' .
02470     ^ 0
02471 
02472                                     addStain
02473   
02474   addWallStain: s=CWallStain ->* 
02475   |
02476     new=CWallStain
02477     color=CFrogNum
02478     type=CFrogNum
02479     stains=CFrogArray
02480   |
02481     s->added _ 1 .
02482     (s->door hasClass: CDoor) ifTrue: [
02483       s->door->stains add: s .
02484       ^ 0 .
02485     ] .
02486     wall_stains size > 256 ifTrue: [
02487       wall_stains removeAt: 0 .
02488     ] .
02489     wall_stains add: s .
02490     stains _  (stains_grid at: s->tile_x / 4 ) at: s->tile_y / 4 .
02491     stains add: s .
02492     ^ 0 .
02493 
02494                                 addTileTemplate
02495   
02496   addTileTemplate: t=CTileTemplate 
02497   ->*
02498   |
02499   |
02500     tile_templates at: t->tile_idx put: t 
02501 
02502                                   afterRestore
02503   
02504   afterRestore->* |
02505     template=C3DThingTemplate
02506     gx=CFrogNum
02507     gy=CFrogNum
02508     col=CFrogArray
02509     old_doors=CFrogArray
02510     old=C3DWorldManager
02511   |
02512   
02513     wall_stains _ #() .
02514     floor_stains _ #() .
02515   
02516     self restoreBlocksFromString: blocks_string withWidth: blocks_width withHeight: blocks_height .
02517   
02518     CFrogTime setTime: game_load_tS .
02519   
02520     self updateDoorMatrix .
02521    
02522     #world _ self . 
02523     is_tainted _ 1 .
02524 
02525                                     animate
02526   
02527   animate ->*
02528   |
02529     t=CFrogArray
02530     p=CPlayer
02531   |
02532     is_paused ifTrue: [
02533       ^0 
02534     ] .
02535    
02536     p _ self getPlayer .
02537    
02538     (self getThingsInRadiusFromX: p->x fromY: p->y withRadius: 32 * 128) do: [:t*|
02539       t animate .
02540     ] .
02541     self updateParticles .
02542     self updateLines .
02543     day_night update .
02544     doors do:[:d=CDoor|
02545       d update .
02546     ] .
02547 
02548                                    beforeSave
02549   
02550   beforeSave ->*
02551     |
02552     |
02553     game_load_tS _ CFrogTime now asSeconds .
02554     blocks_string _ self saveBlocksToString .
02555     blocks_width _ self width .
02556     blocks_height _ self height .
02557     thing_templates doKeys:[:k=CFrogStr|
02558       (thing_templates at: k ) save .
02559     ] .
02560     tile_templates do:[:t=CTileTemplate |
02561       (t hasClass: CTileTemplate) ifTrue: [
02562         t save
02563       ] .
02564     ] .
02565 
02566                              connectToServerAtPort
02567   
02568   connectToGameAt: addr=CFrogStr atPort: p=CFrogNum ->*
02569   |
02570     recur=CFrogBlock
02571   |
02572     addr show .
02573     p show .
02574     #client _ C3DWorldClient basicNew .
02575     #client connectToServer: addr atPort: p .
02576     is_client _ 1 .
02577 
02578                                   doorInRadius
02579   
02580   doorInRadius: r=CFrogNum 
02581     atX: x=CFrogNum
02582     atY: y=CFrogNum
02583     atAngle: a=CFrogNum 
02584       ->CDoor
02585   |
02586   |
02587     r _ r / 128 .
02588     x _ x / 128 .
02589     y _ y / 128 .
02590     -1 to: 2 do:[:xoff=CFrogNum|
02591       -1 to: 2 do:[:yoff=CFrogNum|
02592         ((grid at: x / 16 + xoff)
02593           at: y /16 + yoff) do:[:d=CDoor|
02594            (d hasClass: CDoor) ifTrue: [    
02595              ((d ->x + .5 - x ) squared + (d->y + .5 - y) squared ) sqrt < 2 ifTrue: [
02596               ^ d
02597             ]
02598           ]
02599         ]
02600       ]
02601     ]. 
02602     ^ 0 
02603 
02604                               getClientFromPlayer
02605   
02606   getClientFromPlayer: p=CPlayer
02607   ->C3DWorldClient
02608   |
02609   |
02610     clients do: [:c=C3DWorldClient|
02611       c->player = p ifTrue: [
02612         ^ c
02613       ]. 
02614     ] .
02615 
02616                               getObstaclesInRadius
02617   
02618   getObstaclesInRadiusForThing: t=C3DThing inRadius: r=CFrogNum
02619     ->CFrogArray 
02620   |
02621     ret=CFrogArray
02622   |
02623     ret _ #() .
02624     (self getThingsInRadiusFromX: t->x fromY: t->y withRadius: r) do: [:canidate=C3DThing|
02625       canidate->health > 0 ifTrue: [
02626         (canidate hasClass: CPickup)ifFalse: [
02627            ret add: canidate
02628         ].
02629       ] .
02630     ] .
02631     ^ ret
02632   
02633 
02634                                getPlatformHeight
02635   
02636   useless->*
02637   ||
02638    ^ 0
02639 
02640                              handleMessageForClient
02641   
02642   handleMessage: m=CFrogStr forClient: c=C3DWorldClient 
02643   ->*
02644   |
02645     type=CFrogStr
02646     array*
02647     p=CPlayer
02648     thing*
02649     x_pos=CFrogNum
02650     y_pos=CFrogNum
02651     z_pos=CFrogNum
02652     things=CFrogArray
02653     best_thing=C3DThing
02654     best_dist=CFrogNum
02655     closest=CFrogBlock
02656     delegate=CFrogNum
02657     proj*
02658   |
02659     delegate=0 .
02660     best_dist _ 100000 .
02661   
02662   'Closest item with ID to point'.
02663     closest _ [:x=CFrogNum :y=CFrogNum :z=CFrogNum :id=CFrogNum |
02664       things _ self getThingsInRadiusFromX: x fromY: y withRadius: 8 * 64 .
02665       best_thing _ things first .
02666       things do:[:t=C3DThing|
02667         ((t->x - x) squared + (t->y - y) squared + ((t->z - z) *128) squared ) <
02668         best_dist 
02669           ifTrue: [
02670            t ->server_id = id ifTrue: [
02671              best_thing _ t .
02672            ]
02673         ].
02674       ].
02675       best_thing 
02676     ] .
02677   
02678     m size < 5 ifTrue: [
02679       c->sock close .
02680       ^ 0. .
02681     ] .
02682     type _ m copyFrom: 0 to: 4 .
02683     m _ m copyFrom: 5 to: m size .
02684     array _ m restoreThing .
02685     type show .
02686     type = 'PBlk' ifTrue: [
02687       'Place block ' .
02688       'Use 0 for remove block' . 
02689       self setTile: array first
02690         atX: (array at: 1)
02691         atY: (array at: 2)
02692         atZ: (array at: 3) .
02693       delegate _ 1 .
02694     ] . 
02695     type = 'Piss' ifTrue: [
02696       p _ c->player .
02697       p->angle _ array first .
02698       p->angle2 _ array at: 1 .
02699   'piis' show .
02700       p piss . 
02701     ] .
02702     type = 'PThg' ifTrue: [
02703       'Place a Thing'.
02704       thing _ (CFrogClass fromString: array first) new .
02705       thing ->x _ array at: 1 .
02706       thing ->y _ array at: 2 .
02707       thing ->z _ array at: 3 .
02708       self removeFromGrid: thing .
02709       self updateThingPos: thing .
02710       thing ->x show .
02711       thing ->y show .
02712       thing ->z show .
02713       thing show .
02714     ].
02715     type = 'PMov' ifTrue: [
02716       'Player move' show .
02717        p _ c->player .
02718        p->x show .
02719        p->y show .
02720        p->z show .
02721        self removeFromGrid: p .
02722        p->x _ array first .
02723        p->y _ array at: 1 .
02724        p->z _ array at: 2 .
02725        p->angle _ array at: 3 .
02726        self updateThingPos: p .
02727     ] .
02728     type = 'Damg' ifTrue: [
02729       'Damage Entity closest to point' .
02730       '(x y z dmg server_id)'.
02731       best_thing _ closest value: array first 
02732          value: (array at:1)
02733          value: (array at:2) 
02734          value: (array at:4) .
02735       'damage' show .
02736       best_thing show .
02737       best_thing damage: (array at: 3) from: c->player .
02738     ] .
02739     type = 'EBlC' ifTrue: [
02740       delegate _ 1 .
02741     ] .
02742     type = 'EBlW' ifTrue: [
02743       delegate _ 1 .
02744     ] .
02745     type = 'EBlF' ifTrue: [
02746       delegate _ 1 .
02747     ] .
02748     type = 'PkUp' ifTrue: [
02749        'Pickup item' .
02750       best_thing _ closest value: array first 
02751          value: (array at:1)
02752          value: (array at:2)
02753          value: (array at:3) .
02754       (best_thing hasClass: CPickup) ifTrue: [
02755         best_thing addToPlayer: c->player .
02756         self removeThing: best_thing .
02757       ] .
02758     ] . 
02759   
02760     type = 'Proj' ifTrue: [
02761       proj _ (array first ) new .
02762       proj->from _ c->player .
02763       proj->x _ array at: 1 .
02764       proj->y _ array at: 2 .
02765       proj->z _ array at: 3 .
02766       proj->momx _ array at: 4 .
02767       proj->momy _ array at: 5 .
02768       proj->momz _ array at: 6 .
02769       proj->angle _ proj->momx arg: proj->momy .
02770     ] .
02771   
02772   
02773     delegate ifTrue: [
02774       clients do: [:c2=C3DWorldClient|
02775         c ~= c2 ifTrue: [
02776           c2 sendMessage: array withType: type .
02777         ].
02778       ] .
02779     ] .
02780   
02781 
02782                                  handlePowerups
02783   
02784   handlePowerups ->* |
02785     p=CPlayer
02786     things=CFrogArray 
02787     do_it=CFrogBlock
02788     client=C3DWorldClient
02789   |
02790     do_it _ [:p=CPlayer|
02791       things _ self getThingsInRadiusFromX: p->x fromY: p->y withRadius: 64 .
02792       things do: [:pu=CPickup |
02793         (pu hasClass: CPickup ) ifTrue: [
02794           'canSeeThing doesnt acount for angles tahnkfully(we are alreadt in radius)' .
02795           (pu canSeeThing: p) ifTrue: [
02796             pu addToPlayer: p .
02797             is_server ifTrue: [
02798                client sendPickupToClient: pu .
02799             ] .          
02800           ].
02801         ]
02802       ]
02803     ] . 
02804     is_server ifTrue: [
02805       clients do:[:c=C3DWorldClient |
02806        client _ c .
02807         do_it value: client->player
02808       ] .
02809     ] ifFalse: [
02810       is_client ifFalse: [
02811         p _ self getPlayer .
02812         do_it value: p .
02813       ]
02814     ]. 
02815 
02816                                  hostGameAtPort
02817   
02818   hostGameAt: str=CFrogStr atPort:  p=CFrogNum ->*
02819   |
02820     recur=CFrogBlock
02821   |
02822     is_server _ 1 .
02823    str show .
02824    p  show .
02825     blocks_string _ self saveBlocksToString .
02826     blocks_width _ self width .
02827     blocks_height _ self height .
02828     server_sock _ CAsyncStream newServerAt: str atPort: p  .
02829     recur _ [
02830       server_sock acceptWithCallback: [:w* :c* |   
02831   'Retrigger callback' show .
02832         c _ self addClient: c .
02833         recur value .
02834       ].
02835     ].
02836   
02837     recur value .
02838   
02839 
02840                                 isObstacleAtXAtY
02841   
02842   isObstacleForThing: thing=C3DThing atX: x=CFrogNum atY: y=CFrogNum
02843     withRadius: r=CFrogNum
02844     ->CFrogNum
02845   |
02846     tt=C3DThing
02847   |
02848     x _ (x / 128) floor .
02849     y _ (y / 128) floor .
02850     r _ r * r.
02851     -1 to: 2 do:[:xo=CFrogNum|
02852       -1 to: 2 do:[:yo=CFrogNum|
02853         ((grid at: x + xo ) at: y + yo) do:[:t*|
02854           (t ~= thing) ifTrue: [
02855             (t hasClass: C3DThing) ifTrue: [
02856               tt _ t .
02857               ((x * 128 - tt->x) squared + (y * 128 - tt->y) squared ) < r ifTrue: [
02858                 tt->health > 0. ifTrue: [
02859                   ^ 1 .
02860                 ] .
02861               ].
02862             ].
02863           ]
02864         ].
02865       ] .
02866     ] .
02867     ^ 0 .
02868 
02869                                     lighting
02870   
02871   lighting ->* 
02872   |
02873   |
02874     lights do:[:l=CLight|
02875       l update .
02876     ] .
02877     self skylight: sky_light .
02878   
02879 
02880                                newExplosionLight
02881   
02882   newExplosionLightAtX: x=CFrogNum atY: y=CFrogNum atZ: z=CFrogNum withLevel: l=CFrogNum ->CLight
02883   |
02884     light=CLight
02885   |
02886     light _ CLight new .
02887     light->x _ x .
02888     light->y _ y .
02889     light->z _ z .
02890     light->level _ l min: 15 .
02891     lights add: light .
02892     light->start_tS _ CFrogTime now asSeconds .
02893     light update .
02894 
02895                                     newGrid
02896   
02897   initGrid ->* 
02898   |
02899    gx=CFrogNum
02900    gy=CFrogNum
02901    col=CFrogArray 
02902   |
02903   'INIT GRID ' show.
02904   self width show .
02905     'the world_handle field is set in 3D.HC'. 
02906     gx _ (self width + 4 ) / 4 .
02907     gy _ (self height + 4 ) / 4 .
02908   
02909   
02910     grid _ #() .
02911   
02912     0 to: gx do: [:a=CFrogNum|
02913       col _ # () .
02914       0 to: gy do: [:b=CFrogNum|
02915         col add: #() 
02916       ].
02917       grid add: col .
02918     ] .
02919   
02920   
02921     'Stains grid is 4x4'.
02922     stains_grid _ #() .
02923   
02924     gx _ (self width + 4 ) / 4 .
02925     gy _ (self height + 4 ) / 4 .
02926     0 to: gx do: [:a=CFrogNum|
02927       col _ # () .
02928       0 to: gy do: [:b=CFrogNum|
02929         col add: #() 
02930       ].
02931       stains_grid add: col .
02932     ] .
02933   
02934     'Doors grid is 16x16' .
02935   
02936     doors_grid _ #() .
02937   
02938     gx _ (self width + 16 ) / 16 .
02939     gy _ (self height + 16 ) / 16 .
02940     0 to: gx do: [:a=CFrogNum|
02941       col _ # () .
02942       0 to: gy do: [:b=CFrogNum|
02943         col add: #() 
02944       ].
02945       doors_grid add: col .
02946     ] .
02947   
02948 
02949                                   newLandscape
02950   
02951   newLandscapeWithWidth: w=CFrogNum withHeight: h=CFrogNum
02952     -> C3DWorldManager 
02953   |
02954     ret=C3DWorldManager
02955     player=CPlayer
02956     grid_sz=CFrogNum
02957     r=CFrogRandom
02958     vectors=CFrogArray
02959     tmp=CFrogArray
02960     angle=CFrogNum
02961     vector=CFrogArray
02962     g1=CFrogNum
02963     g2=CFrogNum
02964     g3=CFrogNum
02965     g4=CFrogNum
02966     lerp=CFrogBlock
02967     gx=CFrogNum
02968     gy=CFrogNum
02969     x1=CFrogNum
02970     x2=CFrogNum
02971     col=CFrogArray
02972     fill_with=CFrogBlick
02973   |
02974     r _ CFrogRandom new .
02975     ret _ self .
02976     #world _ ret .
02977     ret emptyWorldWithWidth: w withHeight: h .
02978     player _ CPlayer new .
02979     player -> x _ w * 128 / 2 + 64 . 
02980     player -> y _ h * 128 / 2 + 64 . 
02981   
02982     grid_sz _ 10 .
02983   
02984     vectors _ #() .  
02985     
02986     'Perlin noise' .
02987   
02988     0 to: (w / grid_sz) ceil + 1 do: [:x=CFrogNum|
02989       tmp _ #() .
02990       0 to: (h / grid_sz) ceil + 1 do: [:y=CFrogNum|
02991         angle _ r next * 6.28 .
02992         tmp add: #((angle cos ) (angle sin )) .
02993       ] .
02994       vectors add: tmp .
02995     ] .
02996   
02997     lerp _ [:a=CFrogNum :b=CFrogNum :v=CFrogNum |
02998        a + ((b - a )*v)
02999     ].
03000   
03001     'Dirt' .
03002     fill_with _ 3 . 
03003   
03004     0 to: w  do: [:x=CFrogNum|
03005       0 to: h do: [:y=CFrogNum|
03006         gx _ x rem: grid_sz .
03007         gy _ y rem: grid_sz .
03008   
03009         vector _ ((vectors at: x / grid_sz) at: y /grid_sz) .
03010         g1 _ ((gx / grid_sz ) * (vector at: 0)) + 
03011           ((gy / grid_sz ) * (vector at: 1 )).
03012   
03013         vector _ ((vectors at: x / grid_sz + 1) at: y / grid_sz  ) .
03014         g2 _ ((1 - (gx / grid_sz)) negated  * (vector at: 0)) + 
03015           ((gy / grid_sz ) * (vector at: 1 )).
03016   
03017         vector _ ((vectors at: x / grid_sz ) at: y /grid_sz + 1) .
03018         g3 _ ((gx / grid_sz ) * (vector at: 0)) + 
03019           ((1 - (gy / grid_sz)) negated * (vector at: 1 )).
03020   
03021         vector _ ((vectors at: x / grid_sz + 1) at: y / grid_sz + 1) .
03022         g4 _ ((1 - (gx / grid_sz)) negated * (vector at: 0)) + 
03023           ((1 -  (gy / grid_sz)) negated  * (vector at: 1 )).
03024   
03025   
03026         x1 _ lerp value: g1 value: g2 value: gx / grid_sz .
03027         x2 _ lerp value: g3 value: g4 value: gx / grid_sz .
03028   
03029         x1 _ lerp value: x1 value: x2 value: gy / grid_sz .
03030         0 to: x1 * 6 + 20 do: [:z=CFrogNum |
03031           #world setTile: fill_with atX: x atY: y atZ: z .
03032         ] .
03033       ].
03034     ] .
03035   
03036     ^ ret .
03037 
03038                                   newParticle
03039   
03040   newParticleAtX: x=CFrogNum atY: y=CFrogNum
03041     atZ: z=CFrogNum
03042     withSpread: s=CFrogNum 
03043     withColor: c=CFrogNum 
03044   ->*
03045   |
03046   |
03047     is_server ifTrue: [
03048       clients do: [:cl=C3DWorldClient |
03049         cl sendMessage: #(
03050           x y z  s c 0
03051         ) withType: 'NPrt' .
03052       ] . 
03053     ] .
03054     self basicNewParticleAtX: x atY: y atZ: z withSpread: s
03055     withColor: c
03056 
03057                               newParticleWithSplat
03058   
03059   newParticleAtX: x=CFrogNum atY: y=CFrogNum
03060     atZ: z=CFrogNum
03061     withSpread: s=CFrogNum 
03062     withColor: c=CFrogNum 
03063     withSplatLump: sp=CFrogStr
03064   ->*
03065   |
03066   |
03067   
03068     is_server ifTrue: [
03069       clients do: [:cl=C3DWorldClient |
03070         cl sendMessage: #(
03071           x y z  s c sp
03072         ) withType: 'NPrt' .
03073       ] . 
03074     ] .
03075   
03076     self basicNewParticleAtX: x atY: y atZ: z withSpread: s
03077     withColor: c withSplatLump: sp.
03078 
03079                                      pause
03080   
03081   pause->*
03082   |
03083   |
03084    is_client ifFalse: [
03085   'PAUSE' show .
03086      CFrogTime pause .
03087   'poo0'show.
03088      is_paused _ 1 .
03089   'poo1'show.
03090      is_paused show .
03091   'poo2'show.
03092    ] .
03093 
03094                                   recv3DThing
03095   
03096   recv3DThing: args=CFrogArray ->*
03097   |
03098     t=C3DThing
03099   |
03100     t=C3DThing new .
03101     t->x _ args at:0 . 
03102     t->y _ args at:1 . 
03103     t->z _ args at:2 . 
03104     t->momx _ args at:3 . 
03105     t->momy _ args at:4 . 
03106     t->momz _ args at:5 . 
03107     t->angle _ args at:6 . 
03108     t->health _ args at:7 . 
03109     t->template _ self getThingTemplate: (args at: 8) .
03110     t->animation_start_tS _ args at: 9 . 
03111     t->animation_no_repeat _ args at: 10 . 
03112 
03113                               recv3DThingTemplate
03114   
03115   recv3DThingTemplate: props=CFrogArray
03116    ->*
03117   |
03118     t=C3DThingTemplate
03119   |
03120     t _ thing_templates at: props first . 
03121     (t hasClass: C3DThingTemplate) ifFalse: [
03122       t _ C3DThingTemplate new .
03123       t->name _ props first .
03124       self addThingTemplate: t withName: props first .
03125     ] .
03126   
03127     t->front _ CFrogImg get: (props at: 1 ).
03128     t->side _ CFrogImg get: (props at: 2 ).
03129     t->back _ CFrogImg get: (props at: 3 ).
03130   
03131     t->front setGraphicsFromString: (props at:4 ). 
03132     t->side setGraphicsFromString: (props at:5 ).
03133     t->back setGraphicsFromString: (props at:6 ).
03134   
03135 
03136                                  recvBlockEdit
03137   
03138   recvBlockEdit: args=CFrogArray ->*
03139   |
03140   |
03141     self setTile: (args at: 0)
03142      atX: (args at: 1)
03143      atY: (args at: 2)
03144      atZ: (args at: 3)
03145 
03146                                   removeThing
03147   
03148   removeThing: t=C3DThing ->* | |
03149     self removeFromGrid: t .
03150     things remove: t .
03151   
03152 
03153                             restoreBlocksFromString
03154   
03155   
03156 
03157                                saveBlocksToString
03158   
03159   
03160 
03161                                sendLinestoClient
03162   
03163   sendLinesToClient: c=C3DWorldClient ->*
03164   |
03165   |
03166     (lines hasClass: CFrogArray) ifTrue: [
03167       c sendMessage: lines withType: 'Line'.
03168     ] ifFalse: [
03169       c sendMessage: #() withType: 'Line'.
03170     ] .
03171     
03172 
03173                                sendThingsToClient
03174   
03175   sendThingsToClient: c=C3DWorldClient ->*
03176   |
03177     p=CPlayer
03178     to_send=CFrogArray
03179     struct=CFrogArray
03180     now=CFrogNum
03181   |
03182     now _ CFrogTime now asSeconds.
03183     p _ c->player .
03184     to_send _ #world getThingsInRadiusFromX: p->x fromY: p->y  withRadius: 32 * 128 .
03185     struct _ #() .
03186     to_send do:[:t=C3DThing |
03187       (t ~= p ) ifTrue: [
03188         struct add: #(
03189           t->x 
03190           t->y
03191           t->z
03192           t->angle
03193           (t class)
03194           (t->template->name)
03195           t->server_old_x
03196           t->server_old_y
03197           t->server_old_z
03198           t->health
03199           t->animation_no_repeat
03200           (t->animation_start_tS - now)
03201           t->server_id
03202         ) .
03203       ] .
03204     ] . 
03205     c sendMessage: struct withType: 'SThg' .
03206 
03207                                   thingsInPath
03208   
03209   thingsInDist: dist=CFrogNum atAngle: angle=CFrogNum fromThing: thing=C3DThing 
03210     ->CFrogArray
03211     | 
03212     gx=CFrogNum
03213     gy=CFrogNum
03214     ret=CFrogArray
03215     add_thing*
03216     cos=CFrogNum
03217     sin=CFrogNum
03218     tmp=CFrogArray
03219     step=CFrogNum
03220     x=CFrogNum
03221     y=CFrogNum
03222     |
03223     cos _ angle cos .
03224     sin _ angle sin .
03225     ret _ #() .
03226     x _ thing ->x .
03227     y _ thing ->y .
03228     add_thing _ [:bx=CFrogNum :by=CFrogNum |
03229       tmp _ (grid at: bx ) at: by .
03230       tmp do: [:t=C3DThing |
03231         (t hasClass: C3DThing ) ifTrue: [
03232   'IndexOF' show .
03233   ret size show .
03234   t show .
03235           (ret indexOf: t) = -1 ifTrue: [
03236              ret add: t
03237           ] 
03238         ].
03239       ].
03240     ].
03241     step _ 0 .
03242     [ step < (dist + ( 128 * 4 * 1.4 ))] whileTrue: [
03243       gx _ x + (step * cos) .
03244       gy _ y + (step * sin) .
03245       -1 to: 2 do: [:xo=CFrogNum |
03246         -1 to: 2 do: [:yo=CFrogNum |
03247         add_thing value: gx / 128 / 4 + xo value: gy / 128 / 4 + yo .
03248         ] .
03249       ] .
03250       step _ step +  ( 128 * 4 ) .
03251     ] .
03252     ^ ret 
03253   
03254 
03255                                     unpause
03256   
03257   unpause ->* || 
03258     is_client ifFalse: [
03259   'UNPAUSE' show.
03260       CFrogTime unpause.
03261       is_paused _ 0 .
03262     ]
03263 
03264                                   updateLines
03265   
03266   updateLines ->* |
03267     tmp=CFrogArray
03268     line=C3DLine
03269     line2=C3DLine
03270     ps=CPissStream
03271     lnb=CLightningBolt
03272   |
03273     '(Temporary)let server do the lines'.
03274     (#client hasClass: C3DWorldClient) ifTrue: [
03275       ^ 0
03276     ] .
03277   
03278     'Send lines to level' .
03279     tmp _ #() .
03280     things do: [:t* |
03281       (t hasClass: CEggplantMan) ifTrue: [
03282         tmp add: t->left_arm .
03283         tmp add: t->right_arm .
03284       ] .
03285       ((t hasClass: CFrogNPC) or: (t hasClass: CPorky))ifTrue: [
03286        tmp add: t->tongue .
03287        line _ t->tongue .
03288        line->x0 _ t->x .
03289        line->y0 _ t->y .
03290        line->z0 _ t->z + .5 .
03291       ].
03292       (t hasClass: CAssBird) ifTrue: [
03293         lnb _ t->lightning_bol .
03294         tmp addAll: lnb->links .
03295         1 to: lnb->links size do: [:n=CFrogNum|
03296           line _ lnb ->links at: n .
03297           line2 _ lnb ->links at: n - 1 .
03298           line2->x0 _ line->x .
03299           line2->y0 _ line->y .
03300           line2->z0 _ line->z .
03301         ].
03302         tmp addAll: ps->links .
03303   
03304       ]
03305       ((t hasClass: CPlayer) or: (t hasClass: CZombie)) ifTrue: [
03306         ps _ t->piss_stream .
03307         line _ ps->links first .
03308         line->x0 _ line->x - line->momx .
03309         line->y0 _ line->y - line->momy .
03310         line->z0 _ line->z - line->momz  .
03311         1 to: ps->links size do: [:n=CFrogNum|
03312           line _ ps ->links at: n .
03313           line2 _ ps ->links at: n - 1 .
03314           line->x0 _ line2->x .
03315           line->y0 _ line2->y .
03316           line->z0 _ line2->z.
03317         ].
03318         tmp addAll: ps->links .
03319       ].
03320     ] .
03321     lines _ tmp select: [:f*|
03322       f hasClass: C3DLine
03323     ].
03324 
03325                                   CONSTRUCTOR
03326   
03327   init ->* |
03328     e*
03329     e2*
03330     handled=CFrogNum
03331     next_refresh=CFrogNum
03332     now=CFrogNum
03333     player=CPlayer
03334     up=CFrogNum
03335     down=CFrogNum
03336     left=CFrogNum
03337     right=CFrogNum
03338     jump=CFrogNum
03339     shift=CFrogNum
03340     idx=CFrogNum
03341     ldown=CFrogNum
03342     rdown=CFrogNum
03343     hand_animate_state=CFrogStr
03344     hand_animate_mom_x=CFrogNum
03345     hand_animate_mom_y=CFrogNum
03346     hand_animate_gravity=CFrogNum
03347     hand_animate_xoff=CFrogNum
03348     hand_animate_yoff=CFrogNum
03349     hand_active=CFrogNum
03350     xdiff=CFrogNum
03351     ydiff=CFrogNum
03352     ask_exit=CFrogBlock
03353     ask_exit_active=CFrogNum
03354     last_lighting_tS=CFrogNum
03355     notification=CUINotification
03356     poopidex_active=CFrogNum
03357     want_item=CHandItem
03358   |
03359     draw_it_name _ 'Draw3DWorld' .
03360   
03361     on_init _ [
03362       player _ #world getPlayer .
03363       (#ui_root2 hasClass: CUIElem ) ifFalse: [
03364         #ui_root2 _ CUIElem new .
03365         #ui_root2->sz_x _ 640 .
03366         #ui_root2->sz_y _ 480 .
03367       ] .
03368   
03369   
03370       #world unpause .
03371       #ms_grabbed _ 1 .
03372       poopidex_active _  0 .
03373       up _ 0 . 
03374       down _ 0 . 
03375       left _ 0 . 
03376       right _ 0 .
03377       jump _ 0 . 
03378   
03379       ldown _ 0 .
03380       rdown _ 0 .
03381   
03382       hand_animate_state _ 'Normal' .
03383       hand_animate_mom_x _ 0 .
03384       hand_animate_mom_y _ 0 .
03385       hand_animate_xoff _ 320 .
03386       hand_animate_yoff _ 300 .
03387       hand_active _ 1 .
03388       ask_exit_active _ 0 .
03389   
03390       ask_exit _ [
03391        player->main_inventory_active ifTrue: [
03392          player->main_inventory_active ifTrue: [
03393            player toggleMenu.
03394          ] .
03395        ] ifFalse: [
03396         #ui_root removeChild: e. 
03397         
03398         (e hasClass: CUIElem ) ifTrue: [
03399          #ui_root removeChild: e .
03400          #ms_grabbed _ 1 .
03401          ask_exit_active _ 0 .
03402          e _ 0 .
03403          #world unpause
03404         ] ifFalse: [
03405           'Checks if client for us' .
03406           #world pause .
03407   
03408           e _ CUIBackground new .
03409           e->bg_color _ #color_DKGRAY .
03410           e2 _ CUIList new: #(
03411             #('Yes,fuck this poopy garbage' [
03412               #ui_root removeChild: e .
03413               exited _ 1 .
03414               #world unpause
03415             ]) 
03416             #('No,I like this shit(correct aswer)' [
03417               #ms_grabbed _ 1 .
03418               #ui_root removeChild: e .
03419               ask_exit_active _ 0 .
03420               'Diry hack,dont fire weapon on press ' .
03421               ldown _ 0 . 
03422               handled _ 1 .
03423               e _ 0 .
03424               #world unpause
03425             ]) 
03426           ) .
03427           e->sz_x _ e2->sz_x .
03428           e->sz_y _ e2->sz_y + 10 .
03429           e addChild: e2 .
03430           e2->y _ 10 .
03431           e2 _ CUILabel new .
03432           e2->color _ #color_LTCYAN .
03433           e2 setLabel:  'Quit the AssLicking Game?' .
03434            e2->y _ 2 .
03435           e2->x _ e->sz_x - e2->sz_x / 2 .
03436           e addChild: e2 .
03437   
03438           e ->x _ 320 - (e ->sz_x /2 ) .
03439           e ->y _ 240 - (e ->sz_y /2 ) .
03440           #ui_root addChild: e .
03441           ask_exit_active _ 1 .
03442           handled _ 1 .
03443   'Game will be paused,so we wont check for ask_exit_active' .
03444           #ms_grabbed _ 0 .
03445         ] .
03446        ].
03447       ] .
03448   
03449       notification _ CUINotification new: 'Press "T" for things menu' .
03450       notification setIcon: 'Icons/Button'.
03451       notification addToPoopidexCategory: 'Controls/Main' withDescription: 'Edit Things properies or add them to inventory'.
03452       notification _ CUINotification new: 'Press "B" for Blocks Menu' .
03453       notification setIcon: 'Icons/Button' .
03454       notification addToPoopidexCategory: 'Controls/Main' withDescription: 'Edit/Add blocks to inventroy '.
03455     ] . 
03456   
03457     next_refresh _ CFrogTime now asSeconds .
03458     on_event _ [:v=CUIEvent |
03459        player _ #world getPlayer .
03460        handled _ 0 .
03461        #world->is_paused ifTrue: [
03462          v->type='KeyDown' ifTrue: [
03463            'CH_ESC' .
03464            v->m1 = 27 ifTrue: [
03465              handled _ 1 .
03466              ask_exit value .
03467            ] .
03468            'CH_SHIFT_ESC' .
03469            v->m1 = 28 ifTrue: [
03470              handled _ 1 .
03471              ask_exit value .
03472            ] .
03473          ]
03474        ] ifFalse: [
03475        v->type = 'MsLUp' ifTrue: [
03476          ldown _ 0 .
03477        ].
03478        v->type = 'MsRUp' ifTrue: [
03479          rdown _ 0 .
03480        ].
03481        v->type = 'MsLDown' ifTrue: [
03482          ldown _ 1 .
03483          #ms_grabbed ifTrue: [
03484            'Handled because we are firing rhe weaepon during refresh' .
03485            handled _ 1 .
03486          ] .
03487        ] .
03488        v->type = 'MsRDown' ifTrue: [
03489          rdown _ 1 .
03490          #ms_grabbed ifTrue: [
03491            'Handled because we are firing rhe weaepon during refresh' .
03492            handled _ 1 .
03493          ] .
03494        ] .
03495        v->type = 'KeyUp' ifTrue: [
03496          v->m1 = 32 ifTrue: [ 'Space'.
03497            jump _ 0 .
03498          ].
03499          'Shiuft released(?)' .
03500          'SCF_SHIFT is not set as shift is not down' .
03501          v->m1 = 0 ifTrue: [
03502             shift _ 0 .
03503             handled _ 1 .
03504          ].
03505          ('', v->m1 asCharactor) uppercase = 'P' ifTrue: [
03506            player->poopidex activate .
03507            handled _ 1 .
03508          ] .
03509          ('' ,v->m1 asCharactor) uppercase = 'W' ifTrue: [
03510            handled _ 1 .
03511            up _ 0 .
03512          ].
03513          ('', v->m1 asCharactor) uppercase = 'S' ifTrue: [
03514            handled _ 1 .
03515            down _ 0 .
03516          ].
03517          ('', v->m1 asCharactor) uppercase = 'A' ifTrue: [
03518            handled _ 1 .
03519            left  _ 0 .
03520          ].
03521          ('', v->m1 asCharactor) = 'd' ifTrue: [
03522            right _ 0 .
03523            handled _ 0 .
03524          ].
03525        ] .
03526        v->type = 'KeyDown' ifTrue: [
03527          'Tab' .
03528          v->m1 = 9 ifTrue: [
03529            handled _ 1 .
03530            player toggleMenu .
03531          ] .
03532          'CH_ESC' .
03533          v->m1 = 27 ifTrue: [
03534            handled _ 1 .
03535            ask_exit value .
03536          ] .
03537          'CH_SHIFT_ESC' .
03538          v->m1 = 28 ifTrue: [
03539            handled _ 1 .
03540            ask_exit value .
03541          ] .
03542          'Shiuft key' .
03543          (v->m1 = 0 and: v->m2 & 512 ) ifTrue: [
03544             shift _ 1 .
03545             handled _ 1 .
03546          ].
03547          'Space '.
03548          v->m1 = 32 ifTrue: [
03549             jump _ 1 .
03550             handled _ 1 .
03551          ].
03552   
03553          idx _ 0 .
03554          '1234567890' do:[:c=CFrogChr | 
03555            v->m1 asCharactor = c ifTrue: [
03556              player selectQuickItemByNum:  idx .
03557              handled _ 1 .
03558            ] .
03559            idx _ idx + 1 .
03560          ] .
03561          
03562          ('' ,v->m1 asCharactor) uppercase = 'I' ifTrue: [
03563            handled _ 1 .
03564            'Toggle invisible' .
03565            player-> invisible _ player-> invisible not .
03566            player ->invisible ifTrue: [
03567              notification _ CUINotification new: 'You are invisible(feel free to edit the world in peace)' .
03568              notification setIcon: 'Icons/Eye'.
03569              player->floating _ 1 .
03570            ] ifFalse: [
03571              notification _ CUINotification new: 'You are now visible again(Enemies will attack you now).' .
03572              notification setIcon: 'Icons/Eye'.
03573              player->floating _ 0 .
03574            ] .
03575          ].
03576          ('' ,v->m1 asCharactor) uppercase = 'W' ifTrue: [
03577            handled _ 1 .
03578            up _ 1.
03579          ].
03580          ('', v->m1 asCharactor) uppercase = 'S' ifTrue: [
03581            handled _ 1 .
03582            down _ 1 .
03583          ].
03584          ('', v->m1 asCharactor) uppercase = 'A' ifTrue: [
03585            handled _ 1 .
03586            left  _ 1 .
03587          ].
03588          ('', v->m1 asCharactor) = 'd' ifTrue: [
03589            right _ 1 .
03590            handled _ 1 .
03591          ].
03592   
03593          'Block editor' .
03594          ('', v->m1 asCharactor) uppercase = 'B' ifTrue: [
03595            hand_active _ 0 .
03596            CBlockEditShell new run .
03597            hand_active _ 1 .
03598            handled _ 1 .
03599          ].
03600   
03601          'Thing editor' .
03602          ('', v->m1 asCharactor) uppercase = 'T' ifTrue: [
03603            hand_active _ 0 .
03604            CThingEditShell new run .
03605            hand_active _ 1 .
03606            handled _ 1 .
03607          ].
03608   
03609   
03610          'Level editor MEta menu' .
03611          ('', v->m1 asCharactor) uppercase = 'L' ifTrue: [
03612            hand_active _ 0 .
03613            CLevelEditShell new run .
03614            hand_active _ 1 .
03615            handled _ 1 .
03616          ].
03617   
03618          
03619          'Door Editor'.
03620          ('', v->m1 asCharactor) = 'D' ifTrue: [
03621            hand_active _ 0 .
03622            CDoorShell new run .
03623            hand_active _ 1 .
03624            handled _ 1 .
03625          ].
03626        ] .
03627        v->type = 'MsMove' ifTrue: [
03628          hand_animate_xoff _ v->m1 - (640 / 2 ) + hand_animate_xoff .
03629          hand_animate_yoff _ v->m2 - (480 / 2 ) + hand_animate_yoff .
03630   
03631          #ms_grabbed ifTrue: [
03632            player -> angle _ player->angle + ((v->m1 - (640 / 2) ) * (3.14 / 30 / 7 )) .
03633            player -> angle2 _ player -> angle2 + ((v -> m2 - (480 / 2) ) * (3.14 / 30 / 7 )) .
03634            player -> angle2 _ player -> angle2 min: 3.14 / 2 .
03635            player -> angle2 _ player -> angle2 max: -3.14 / 2 .
03636            handled _ 1 .
03637          ].
03638        ] .
03639        v->type = 'MsScroll' ifTrue: [
03640          #ms_grabbed ifTrue: [
03641            player selectNextItemByOffset: v->m1 .
03642            handled _ 1 .
03643          ].
03644        ] .
03645        ].
03646   
03647        handled ifFalse: [
03648          #ui_root sendEventToUI: v .
03649        ] .
03650     ] .
03651     on_refresh _ [
03652        player _ #world getPlayer .
03653        #world ->is_tainted ifTrue: [
03654           #ui_root _ 0 .
03655           player regenUI .
03656           #world ->is_tainted _ 0 .
03657        ].
03658        last_lighting_tS < CFrogTime now asSeconds ifTrue: [
03659          last_lighting_tS _ CFrogTime now asSeconds  + 1 .
03660          #world lighting .
03661        ] .
03662        #world ->is_paused ifFalse: [
03663          now _ CFrogTime now asSeconds .
03664          now >= next_refresh ifTrue: [
03665            next_refresh _ now + (1 / 3 ).
03666            #world update .
03667          ] .
03668          player->momx2 _ 0 .
03669          player->momy2 _ 0 .
03670          player->momz2 _ 0 .
03671          ((#world tileIsLiquidAtX: player->x /128 atY: player->y /128  atZ: player->z) or: player->floating ) ifTrue: [
03672            shift ifTrue: [
03673              player swim: 128 /4 atAngle: player->angle atAngle2: -3.14 / 2 .
03674            ].
03675            jump ifTrue: [
03676              player swim: 128 /4 atAngle: player->angle atAngle2: 3.14 / 2  .
03677            ].
03678            up ifTrue: [
03679              player swim: 128 /4 atAngle: player->angle atAngle2: player->angle2 negated .
03680            ] .
03681            down ifTrue: [
03682              player swim: 128 /4 atAngle: player->angle atAngle2: player->angle2  negated + 3.14 .
03683            ] .
03684            left ifTrue: [
03685              player swim: 128 /4 atAngle: player->angle - (3.14 / 2) atAngle2: player->angle2 negated.
03686            ] .
03687            right ifTrue: [
03688              player swim: 128 /4 atAngle: player->angle + (3.14 / 2) atAngle2: player->angle2 negated.
03689            ] .
03690          ] ifFalse: [
03691            jump ifTrue: [
03692              player jump .
03693            ] .
03694            up ifTrue: [
03695              player move: 128 / 4 atAngle: player->angle .
03696            ] .
03697            down ifTrue: [
03698              player move: 128 / 4 atAngle: player->angle  +  3.14  .
03699            ] .
03700            left ifTrue: [
03701              player move: 128 / 4 atAngle: player->angle  - (3.14 / 2 ) .
03702            ] .
03703            right ifTrue: [
03704              player move: 128 / 4 atAngle: player->angle  + (3.14 / 2 ) .
03705            ] .
03706          ].
03707          #world animate. 
03708          #world handlePowerups .
03709          #ms_grabbed ifTrue: [
03710            ldown ifTrue: [
03711              #hand_item fire .
03712            ] .
03713            rdown ifTrue: [
03714              #hand_item altFire .
03715            ] .
03716          ] .
03717          #hand_item animate .
03718          #world physics .
03719   
03720          (hand_active and: ((
03721             player->main_inventory_active
03722           ) or: ask_exit_active) not) ifTrue: [
03723            #ms_grabbed _ 1 .
03724            'Hand item movement'.
03725            hand_animate_xoff < 100 ifTrue: [
03726              hand_animate_xoff _ 100 .
03727            ].       
03728            hand_animate_xoff > 540 ifTrue: [
03729              hand_animate_xoff _ 540 .
03730            ].       
03731            hand_animate_yoff < 300 ifTrue: [
03732              hand_animate_yoff _ 300 .
03733            ].       
03734            hand_animate_yoff > 450 ifTrue: [
03735              hand_animate_yoff _ 450 .
03736            ].
03737   
03738   
03739            hand_animate_gravity _ 40 .
03740   
03741            'If we want to switch hand items'
03742            'Be sure to push move current item towards bottom of screen'.
03743            
03744            (player->want_hand_item hasClass: CHandItem) ifTrue: [
03745              want_item _ player->want_hand_item .
03746              #hand_item->x _ 320 .
03747              #hand_item->y _ 600 .
03748              want_item->x _ #hand_item->x .
03749              want_item->y _ #hand_item->y .
03750            ] ifFalse: [
03751              #hand_item->x _ 320 .
03752              #hand_item->y _ 340 .
03753            ] .
03754   
03755            'base position' .
03756            #hand_item->xoff _ hand_animate_xoff - #hand_item->x .
03757            #hand_item->yoff _ hand_animate_yoff - #hand_item->y .
03758   
03759            xdiff _ #hand_item->x - hand_animate_xoff .
03760            ydiff _ #hand_item->y - hand_animate_yoff .
03761            xdiff abs < hand_animate_gravity ifTrue: [
03762              hand_animate_xoff _ #hand_item -> x .
03763            ] ifFalse: [
03764              hand_animate_xoff _ (xdiff sign * hand_animate_gravity) + hand_animate_xoff.
03765            ] .
03766            ydiff abs < hand_animate_gravity ifTrue: [
03767              hand_animate_yoff _ #hand_item -> y .
03768            ] ifFalse: [
03769              hand_animate_yoff _ (ydiff sign * hand_animate_gravity) + hand_animate_yoff.
03770            ] .
03771          ] ifFalse: [
03772            #ms_grabbed _ 0 .
03773            hand_animate_xoff _ #hand_item->x .
03774            hand_animate_yoff _ #hand_item->y .
03775          ]
03776        ] .
03777     ] .
03778     ^ self 
03779 
03780                                   CONSTRUCTOR
03781   
03782   init->CAlien | |
03783     #world addThing: self .
03784     template _ #world getThingTemplate: 'CAlien' .
03785     state_start_tS _ CFrogTime now asSeconds .
03786     state _ 'Normal' .
03787     random_generator _ CFrogRandom new .
03788     health _ 75 .
03789     no_fall_off_edge _ 1 .
03790     ^ self
03791 
03792                                    damageFrom
03793   
03794   damage: d=CFrogNum from: t=C3DThing ->* ||
03795     1 to: d / 6 + 5 do:[ 
03796       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_RED 
03797     ] .
03798     target _  t .
03799     self damage: d . 
03800 
03801                                      update
03802   
03803   update->* |
03804     w=C3DWorldManager
03805     p=CPlayer
03806     old_x=CFrogNum 
03807     old_y=CFrogNum 
03808     old_z=CFrogNum 
03809     hit_wall=CFrogNum
03810     tS=CFrogNum 
03811     rocket=CEnergyBall
03812     dist=CFrogNum
03813     pickup=CShitItemPickup
03814   |
03815     tS _ CFrogTime now asSeconds.
03816     w _ #world .
03817   
03818     health <= 0 ifTrue: [
03819       state ~= 'Dead' ifTrue: [
03820         'Default item to drop is CEnergyGunPickup ' .
03821         (drop_thing hasClass: CFrogClass) ifFalse: [
03822           drop_thing _ CEnergyGunPickup .
03823         ] .
03824         w sweepSoundForTime: 500 withMin: 40 withMax: 30 .
03825         template _ w getThingTemplate: 'CAlien/Dead' .
03826         animation_start_tS _ tS .
03827         animation_no_repeat _ 1 .
03828         self die .
03829       ] .
03830       state _ 'Dead' .
03831     ] .
03832   
03833     state = 'Dead' ifTrue: [
03834       ^ 1
03835     ] .
03836   
03837     state = 'Normal' ifTrue: [
03838       steps_to_walk _  steps_to_walk - 1 .
03839       template _ w getThingTemplate: 'CAlien' .
03840       animation_no_repeat _ 0 .
03841       old_x _ x .
03842       old_y _ y .
03843       old_z _ z .
03844       
03845       (target hasClass: C3DThing) ifFalse: [
03846         target _ self lookForTarget .
03847       ] .
03848   
03849       'Only walk around if target is defined'.
03850       (target hasClass:C3DThing) ifTrue: [
03851         self wander: 40 / 10 *  3.4 withJumpVelocity: .55 withTarget: target .
03852         ((steps_to_walk <= 0 or: random_generator next < .15 ) and: (self canSeeThing: target)) ifTrue: [
03853           state _ 'Shoot' .
03854           template _ w getThingTemplate: 'CAlien/Shoot' .
03855           animation_no_repeat _ 0 .
03856           animation_start_tS _ tS.
03857           state_start_tS _  tS.
03858           angle _ (target->x - x) arg: (target->y - y) .
03859           'Used for how many shots to shoot too' .
03860           steps_to_walk _ (random_generator next * 3) + 2.5 .
03861         ] .
03862       ] .
03863       steps_to_walk < 0 ifTrue: [
03864         steps_to_walk _ random_generator next * 10 * 3 .
03865       ] .
03866     ] .
03867   
03868     state = 'Shoot' ifTrue: [
03869       template _ w getThingTemplate: 'CAlien/Shoot' .
03870       (tS - state_start_tS) > (175 / 1000.) ifTrue: [
03871         state_start_tS _ tS .
03872   'See above note' .
03873         steps_to_walk _ steps_to_walk - 1 .
03874         w noiseSoundForTime: 100 withMin: 50 withMax: 70 .
03875         rocket _ CEnergyBall new .
03876         rocket->from _ self . 
03877         rocket->x _ x . 
03878         rocket->y _ y . 
03879         rocket->z _ z + .5 .
03880         rocket -> angle _ (target->x - x arg: target->y - y ).
03881         angle _ rocket->angle .
03882         rocket->momx _ rocket->angle cos * 75 .
03883         rocket->momy _ rocket->angle sin * 75 .
03884         dist _ ((target->x - rocket->x) squared +(target->y - rocket->y)) sqrt .
03885         '75 is the shoot force' .
03886         rocket->momz _ (target->z +.5 - rocket->z + ((random_generator next - .5 ) / 2 ) ) / dist * 75 .
03887       ] .
03888       ((self  canSeeThing: target) and: steps_to_walk > 0) ifFalse: [
03889         steps_to_walk _ random_generator next * 10 * 3 .
03890         state _ 'Normal' . 
03891       ]
03892     ] .
03893   
03894 
03895                                   CONSTRUCTOR
03896   
03897   init ->CAssBird | |
03898     #world addThing: self.
03899     state _ 'Wander'.
03900     random_generator _ CFrogRandom new .
03901     template _ #world getThingTemplate: 'CAssBird' .
03902     health _ 60 .
03903     speed _ 5 .
03904     lightning_bolt _ CLightningBolt new.
03905     lightning_bolt -> from _ self .
03906     ^ self
03907   
03908 
03909                                     animate
03910   
03911   animate->*
03912   |
03913   |
03914     lightning_bolt update
03915 
03916                                    damageFrom
03917   
03918   damage: amt=CFrogNum from: t=C3DThing ->* | |
03919     'blood' .
03920     1 to: amt / 6 + 5 do:[ 
03921       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_RED 
03922     ] .
03923    
03924   
03925     'Attack '.
03926     target _ t .
03927     'Ass bird will get bored of attaking after awhile'.
03928     (state ~= 'Chase0' and: state ~= 'Chase1') ifTrue: [
03929       state_start_tS  _ CFrogTime now asSeconds .
03930       state _ 'Chase0' .
03931     ] .
03932   
03933     self damage: amt . 
03934   
03935     'Trigger state change' .
03936     self update .
03937 
03938                                      update
03939   
03940   update->*
03941   |
03942     w=C3DWorldManager
03943     things=CFrogArray
03944     best_dist=CFrogNum
03945     dist=CFrogNum
03946     now=CFrogNum
03947     rocket=CPoopRocket
03948   |
03949   
03950   'The AssBird will just look for dead enemies to ressurect'.
03951   'The AssBird will also not attack if not provoked' .
03952     now _ CFrogTime now asSeconds.
03953     w _ #world .
03954     state show .
03955   
03956     health <= 0 ifTrue: [
03957       floating _ 0 .
03958       (state ~= 'Dead') ifTrue: [
03959          w sweepSoundForTime: 500 withMin: 40 withMax: 17 .
03960          momz _ 0 .
03961          momx _ (random_generator next - .5) * 10 .
03962          momy _ (random_generator next - .5) * 10 .
03963          animation_no_repeat _ 1 .
03964          animation_start_tS _ now .
03965          template _ w getThingTemplate: 'CAssBird/Dead' .
03966          state _ 'Dead' .
03967          self die .
03968       ].
03969       ^ 1
03970     ] .
03971   
03972   
03973     floating _ 1 .
03974   
03975     steps_to_walk _ steps_to_walk - 1 .
03976   
03977     
03978     'Attack for 5 seconds then return to healing dead assholes'.
03979     (state = 'Chase0') ifTrue: [
03980        made_sound ifFalse: [
03981           made_sound _ 1 .
03982           w sweepSoundForTime: 1500 withMin: 30 withMax: 70 .
03983        ] .
03984        now < (state_start_tS + 5) ifTrue: [
03985          speed _ 50 .
03986          'rise above target  before attack' .
03987          self wanderFly: speed withTarget: target .
03988          momz _ (target->z + 1.5 - z) * .1 .
03989          'Wait at least 2 seconds before attempting attack'.
03990          (state_start_tS + 2) < now ifTrue:  [
03991            dist _ (target->x - x ) squared + (target->y - y ) squared  .
03992            dist < (2.5 * 128 ) squared ifTrue: [
03993              w sweepSoundForTime: 500 withMin: 30 withMax: 70 .
03994              lightning_bolt shootAtX: target->x atY: target->y atZ: target->z + .1 .
03995              state _ 'Wander' .
03996              state_start_tS _ now .
03997              target damage: random_generator next * 30 + 20  from: self .
03998              ^ 1 .
03999            ] .
04000            dist < (32  *128) squared ifTrue: [
04001              (steps_to_walk <= 0) ifTrue: [
04002                steps_to_walk _ 10 * .25 .
04003                'TODO angry graphics'.
04004                state_start_tS _ now .
04005                state _ 'Chase1' .
04006                made_sound _ 0 .
04007                angle _ target->x - x arg: target->y - y .
04008                momx _ speed * angle cos .
04009                momy _ speed * angle sin .
04010                momz _ (target->z - z) / dist sqrt * speed .
04011              ] .
04012            ] .
04013          ] .
04014        ] ifFalse: [
04015          state _ 'Wander' .
04016          made_sound _ 0 .
04017        ] .
04018     ] .
04019   
04020     steps_to_walk < 0 ifTrue: [
04021       steps_to_walk _ random_generator next * 10 * 1 . 
04022       (target hasClass: C3DThing) ifFalse: [
04023          target _ self lookForTarget .
04024       ] .
04025       ((target hasClass: C3DThing) and: (self canSeeThing: target)) ifTrue: [
04026         target->health > 0. ifTrue: [
04027           state _ 'Chase0' .
04028           made_sound _ 0 .
04029           state_start_tS _ now .
04030         ]
04031       ] .
04032     ] .
04033   
04034   
04035     state = 'Chase1' ifTrue: [
04036       now > (state_start_tS + 5. ) ifTrue: [
04037         state _ 'Wander' .  
04038         made_sound _ 0 .
04039       ] . 
04040       'Throw shit towards at the player' .
04041       random_generator next < (5 / 10) ifTrue: [
04042         angle _ target->x -x arg: target->y -y .
04043         rocket _ CPoopRocket new .
04044         rocket->from _ self . 
04045         rocket->x _ x . 
04046         rocket->y _ y .
04047         rocket->z _ z +.5 .
04048         rocket -> angle _ angle + ((random_generator next - .5) * (3.14 / 2) ) .
04049         rocket->momx _ rocket->angle cos * 16 .
04050         rocket->momy _ rocket->angle sin * 16 .
04051         dist _ ((target->x - rocket->x) squared +(target->y - rocket->y)) sqrt .
04052         rocket->momz _ (target->z + .5 - rocket->z) / dist * 16 .
04053       ] .
04054       self isOnGround ifTrue: [
04055         state _ 'Wander' .
04056         made_sound _ 0 .
04057       ] .
04058       ^ 1 .
04059     ] .
04060   
04061     (state = 'Wander' ) ifTrue: [
04062       speed _ 25 .
04063       'Look for dead things to ressurect '.
04064       things _ w getThingsInRadiusFromX: x fromY: y withRadius: 10 * 128 .
04065       things _ things select: [:t=C3DThing| t ->health <= 0 and: (t hasClass: CPickup) not ] .
04066       best_dist _ 16000 * 16000 .
04067       things do: [:t=C3DThing|
04068         'TODO check for "Small" enemy(also dont revive other CAssBirds)'.
04069          ((self canSeeThing: t) and: (t hasClass: CAssBird) not) ifTrue: [
04070            dist _ (t->x - x ) squared + (t->y - y) squared .
04071            (dist < best_dist and: (t hasClass: CPlayer) not ) ifTrue: [
04072              best_dist _ dist .
04073              state _ 'Heal0' .
04074              target _ t .
04075              made_sound _ 0 .
04076            ]
04077          ] .
04078       ] .
04079   
04080       (target hasClass: C3DThing) ifFalse: [
04081         self wander: speed .
04082       ] ifFalse: [
04083         self wanderFly: speed withTarget: target .
04084       ] .
04085     ].
04086   
04087     'Get close to entity to heal it'.
04088     state = 'Heal0' ifTrue: [
04089       speed _ 25 .
04090       self wanderFly: speed withTarget: target .
04091       dist _ (target->x - x ) squared + (target->y - y) squared .
04092       dist sqrt show .
04093       dist < (6 * 128) squared ifTrue: [
04094         state _ 'Heal1' .
04095         made_sound _ 0 .
04096         state_start_tS _ now .
04097       ] .
04098     ] .
04099     
04100    'If we are close to an entity,Sink to its level for 1.5 seconds then '.
04101    ' Shit on the target to bring it back to life' .
04102    state = 'Heal1' ifTrue: [
04103      self wanderFly: speed withTarget: target .
04104      (now > (state_start_tS + 1.5 ) and: (self canSeeThing: target)) ifTrue: [
04105        1 to: 15 do:[ 
04106          w newParticleAtX: x atY: y atZ: z +.5 withSpread: 128 withColor: #color_YELLOW .
04107        ] .
04108        'Bring back to life(remove/init)' .
04109        w sweepSoundForTime: 500 withMin: 30 withMax: 70 .
04110        w removeThing: target .
04111        target init .
04112        lightning_bolt shootAtX: target->x atY: target->y atZ: target->z + .1 .
04113        state _ 'Wander' .
04114        made_sound _ 0 .
04115        target _ 0 .
04116      ] ifFalse:  [
04117        'Look for new target if havent found homie in 4 seconds' .
04118        now > (state_start_tS + 4 )  ifTrue: [
04119          made_sound _ 0 .
04120          state _ 'Wander' .
04121          target _ 0 . 
04122        ] .
04123      ] .
04124      ^ 1 .
04125    ].
04126 
04127                                   CONSTRUCTOR
04128   
04129   initFromStream: s=CNetStream 
04130   -> CAsyncStream 
04131   |
04132    buf=CFrogStr
04133    tuple=CFrogArray
04134    want=CFrogNum
04135    code=CFrogNum
04136   |
04137     buf _ '' .
04138     sock _ s . 
04139     ops _ #() .
04140     thread  _ CFrogThread spawn: [
04141        [
04142          sock->closed not
04143        ] whileTrue: [
04144          tuple _ ops first .
04145          (tuple first = 'Rl') ifTrue: [
04146            buf _ sock getLine .
04147            tuple last value: self value: buf.
04148          ] .
04149          (tuple first = 'R') ifTrue: [
04150            want _ (tuple at: 1) .
04151            buf _ (sock getBytes: want) .
04152            tuple last value: self  value: buf .
04153          ] .
04154          (tuple first = 'Acc') ifTrue: [
04155            tuple last value: self  value: sock accept .
04156          ] .
04157          (tuple first = 'U32') ifTrue: [
04158            tuple last value: self  value: sock getU32 .
04159          ] .
04160          ops remove: tuple .
04161          ops size ifFalse: [
04162            CFrogThread yield .
04163          ] .
04164        ] .
04165    ] .
04166     ^ self
04167    
04168 
04169                                 acceptWCallback
04170   
04171   acceptWithCallback: b=CFrogBlock ->* 
04172   |
04173   |
04174     ops add: #( ('Acc') ( b))
04175 
04176                                      close
04177   
04178   close->*
04179   ||
04180     sock close 
04181 
04182                                 newConnectionTo
04183   
04184   initConnectionTo: a=CFrogStr atPort: p=CFrogNum
04185   ->*
04186   |
04187   |
04188     ^ self initFromStream: (CNetStream newConnectionTo: a atPort: p ).
04189 
04190                                   newServerAt
04191   
04192   initServerAt: a=CFrogStr  atPort: p=CFrogNum
04193    ->*
04194   |
04195   |
04196     ^ self initFromStream: (CNetStream newServerAt: a atPort: p ). 
04197 
04198                                readBytesWithBlock
04199   
04200   readBytes: n=CFrogNum withCallback: cb=CFrogBlock
04201   |
04202   |
04203     ops add: #(('R') (n) (cb)  ) .
04204 
04205                               readLineWithCAllback
04206   
04207   readLineWithCallback: cb=CFrogBlock
04208   |
04209   |
04210     ops add: #(('Rl') (cb)  ) .
04211 
04212                                    readU32WCB
04213   
04214   readU32WithCallback: cb=CFrogBlock
04215   |
04216   |
04217     ops add: #(('U32') (cb)  ) .
04218 
04219                                      write
04220   
04221   write: s=CFrogStr 
04222   ->*
04223   |
04224   |
04225     sock sendBytes: s . 
04226 
04227                                    writeLine
04228   
04229   writeLine: s=CFrogStr 
04230   ->*
04231   |
04232   t=CFrogStr
04233   |
04234    t _ s copy .
04235    sock sendBytes: t  
04236 
04237                                     writeU32
04238   
04239   writeU32: n=CFrogNum ->* ||
04240     sock sendU32: n .
04241 
04242                                   CONSTRUCTOR
04243   
04244   init | |
04245     self setGraphics: 'GR/Keys/BigKey' .
04246     max_ammo _ 0 . 
04247     ammo _ 0 .
04248     x _ 0 .
04249     y _ 300 .
04250     xoff _ 0 .
04251     yoff _ 0 .
04252     timeout _ 0 .
04253     inventory_item _ CUIGridItem new .
04254     inventory_item setGraphics: 'GR/Keys/BigKey' .
04255     inventory_item setCount: ammo .
04256     inventory_item setItem: self .
04257     inventory_item ->name _
04258   'Big Key
04259   Big ass fuckin keu
04260   ' .
04261     inventory_item onLeftUp: [
04262       #world getPlayer selectItem: self .
04263     ].
04264     #world getPlayer addInventoryItem: inventory_item.
04265     ^ self
04266   
04267 
04268                                   CONSTRUCTOR
04269   
04270   init | |
04271     count _ 1  .
04272     #world addThing: self .
04273     item_class _ CBigKey .
04274     template _ #world getThingTemplate: 'CBigKeyPickup' .
04275     ^ self
04276   
04277 
04278                                   CONSTRUCTOR
04279   
04280   init ->* |
04281     grid=CUIGrid
04282     item=CUIGridItem
04283     group=CUIBackground
04284     button=CUIButton
04285     scroll_bars=CUIScrollBars
04286     tile*
04287     new_texture=CFrogImg
04288     ui_roots=CFrogArray
04289     handled=CFrogNum
04290     old*
04291     inv_item=CWorldEditBlock
04292     n=CUINotification 
04293     ask_num=CFrogBlock
04294     text_input=CUITextBar
04295     wall_size=CFrogNum
04296     tall_button=CUIButton
04297     web=CWorldEditBlock
04298     popup=CUITextPopup
04299   |
04300   
04301     ask_num _ [:result=CFrogBlock|
04302       popup _ CUITextPopup new .
04303       popup->cb _ [:s=CFrogStr|
04304         result value: s asInteger
04305       ] .
04306       popup run .
04307     ].
04308   
04309   
04310   
04311     on_init _ [
04312       n _ CUINotification new: 'Click Block to For Menu' .
04313       n setIcon: 'Icons/Button' . 
04314       n addToPoopidexCategory: 'Controls/BlockEdit' withDescription: 'Edit a block or add it to the inventory '.
04315       #ms_grabbed _ 0 .
04316       #ui_root _ CUIElem new .
04317       ui_roots _ #(#ui_root) .'I make a stack of UIs that are POPed' .
04318       #ui_root show .
04319       #ui_root -> x _ 0 .
04320       #ui_root -> y _ 0 .
04321       #ui_root -> sz_x _ 640 .
04322       #ui_root -> sz_y _ 480 .
04323       scroll_bars _ CUIScrollBars new .
04324       scroll_bars ->x _ 10 .
04325       scroll_bars ->y _ 10 .
04326       scroll_bars ->sz_y _ 460 .
04327       scroll_bars ->sz_x _ 620 .
04328       scroll_bars->bg_color _ #color_DKGRAY .
04329       grid _ CUIGrid new .
04330       grid setWidth: 16 withHeight: 16 .
04331       1 to: 256 do:[:b=CFrogNum |
04332         item _ CUIGridItem new .
04333         tile _ (#world -> tile_templates at: b) .
04334         item->graphics _  tile->wall_texture  .
04335         (tile hasClass: CTileTemplate) ifTrue: [
04336           item -> item _ tile  .
04337         ] ifFalse: [
04338           item -> item _ b .
04339         ] .
04340         item->cnt _ b .
04341         item onLeftUp: [:elem=CUIGridItem |
04342           wall_size _ 1 .
04343           tile _ elem -> item .
04344           (tile hasClass: CTileTemplate) ifFalse: [
04345             tile _ CTileTemplate new .
04346             tile -> tile_idx _ elem->item .
04347             tile -> tile_idx show .
04348             #world -> tile_templates at: tile->tile_idx put: tile .
04349             elem->item _ tile .
04350           ] .
04351           'Remove old group ' .
04352           group _ CUIBackground new .
04353           ui_roots add: group .
04354           #ui_root _ group .
04355           group-> bg_color _ #color_DKGRAY .
04356           group setHeight: 300 .
04357           group setWidth: 200 .
04358           group->x _ 640 / 2 - (group->sz_x / 2) .
04359           group->y _ 480 / 2 - (group->sz_y / 2) .
04360           
04361           button _ CUIButton new .
04362           button->fg_color _ #color_LTRED .
04363           button->bg_color _ #color_YELLOW .
04364           button setLabel: 'Edit top' .
04365           button onLeftUp: [:elem* |
04366             new_texture _ CFrogImg newFromEditor .
04367             tile setFloor:  new_texture->name.
04368             #client sendEditFloor: new_texture forBlock: tile->tile_idx .
04369           ] .
04370           button-> x _ 50 .
04371           button-> y _ 50 .
04372           button->sz_y _ 40 .
04373           button->sz_x _ 200 .
04374           group addChild: button .
04375   
04376           
04377           button _ CUIButton new .
04378           button->fg_color _ #color_LTRED .
04379           button->bg_color _ #color_YELLOW .
04380           button setLabel: 'Edit Wall' .
04381           button onLeftUp: [:elem* |
04382             new_texture _ CFrogImg newFromEditor .
04383             tile setWall:  new_texture->name .
04384             #client sendEditWall: new_texture forBlock: tile->tile_idx .
04385           ] .
04386           button-> x _ 50 .
04387           button-> y _ 100 .
04388           button->sz_y _ 40 .
04389           button->sz_x _ 200 .
04390           group addChild: button .
04391   
04392           button _ CUIButton new .
04393           button->fg_color _ #color_LTRED .
04394           button->bg_color _ #color_YELLOW .
04395           button setLabel: 'Edit Bottom' .
04396           button onLeftUp: [:elem* |
04397             new_texture _ CFrogImg newFromEditor .
04398             tile setCeil:  new_texture->name.
04399             #client sendEditCeil: new_texture forBlock: tile->tile_idx .
04400           ] .
04401           button-> x _ 50 .
04402           button-> y _ 150 .
04403           button->sz_y _ 40 .
04404           button->sz_x _ 200 .
04405           group addChild: button .
04406   
04407           button _ CUIButton new .
04408           button->fg_color _ #color_LTRED .
04409           button->bg_color _ #color_YELLOW .
04410           button setLabel: 'Add To Players stash' .
04411           button onLeftUp: [:elem* |
04412             web _ CWorldEditBlock new: tile->tile_idx .
04413             web->wall_size _ wall_size
04414             
04415           ] .
04416           button-> x _ 50 .
04417           button-> y _ 200 .
04418           button->sz_y _ 40 .
04419           button->sz_x _ 200 .
04420           group addChild: button .
04421   
04422   
04423           button _ CUIButton new .
04424           tall_button _ button .
04425           button->fg_color _ #color_LTRED .
04426           button->bg_color _ #color_YELLOW .
04427           button setLabel: 'Set wall size(' , wall_size printString ,')' .
04428           button onLeftUp: [:elem* |
04429             ask_num value: [:n=CFrogNum|
04430               wall_size _ n .
04431               tall_button setLabel: 'Set wall size(' , wall_size printString ,')' .
04432             ]
04433           ] .
04434           button-> x _ 50 .
04435           button-> y _ 250 .
04436           button->sz_y _ 40 .
04437           button->sz_x _ 200 .
04438           group addChild: button .
04439   
04440         ] .
04441         grid addItem: item .
04442       ] .
04443   
04444       #ui_root addChild: scroll_bars .
04445       scroll_bars addChild: grid .
04446       grid->x _ 10 .
04447       grid->y _ 10 .
04448     ] .
04449   
04450     on_event _ [:v=CUIEvent |
04451       handled _ 0 .
04452       v->type = 'KeyDown' ifTrue: [
04453         v->m1 = 27 ifTrue: [
04454           'ESC '.
04455           ui_roots size <= 1 ifTrue: [
04456             exited _ 1 .
04457             handled _ 1 . 
04458           ] ifFalse: [
04459   'POP the ui menus until nothing left to pop' .
04460             ui_roots remove: (ui_roots at: ui_roots size - 1) .
04461             #ui_root _ ui_roots at: ui_roots size - 1 .
04462             handled _  1.  
04463           ] .
04464         ] .
04465       ] .
04466       handled ifFalse: [
04467         #ui_root sendEventToUI: v .
04468       ].
04469     ] .
04470   
04471     'Draw world in backgroubnd' .
04472     draw_it_name _ 'Draw3DWorld' .
04473   
04474   
04475     ^ self
04476   
04477   
04478 
04479                                   CONSTRUCTOR
04480   
04481   init | |
04482     is_ceil _ 1 .
04483    ^ self
04484   
04485 
04486                                   CONSTRUCTOR
04487   
04488   init | |
04489     is_ceil_wall _ 1 .
04490     ^ self
04491   
04492 
04493                                   CONSTRUCTOR
04494   
04495   init->CCyberPoop | |
04496     #world addThing: self .
04497     random_generator _ CFrogRandom new .
04498     template _ #world getThingTemplate: 'CCyberPoop' .
04499     template->radius _ 256 .
04500     health _ 300 .
04501     state _ 'Wait' .
04502     ^ self
04503 
04504                                    damageFrom
04505   
04506   damage: amt=CFrogNum from: t=C3DThing ->* | |
04507     'Return if damage came from self(rocket exploded on self)'.
04508      t = self ifTrue: [
04509       ^ 0
04510      ] .
04511   
04512     'blood' .
04513     1 to: amt / 6 + 5 do:[ 
04514       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_BROWN 
04515     ] .
04516    
04517   
04518     'Attack '.
04519     target _ t .
04520     'Pain Chance(interupt attack).'
04521     (random_generator next < .33 ) ifTrue: [
04522       state = 'Chase' .
04523     ] .
04524   
04525     self damage: amt . 
04526   
04527     'Trigger state change' .
04528     self update .
04529 
04530                                      update
04531   
04532   update ->*
04533   |
04534     dist=CFrogNum
04535     w=C3DWorld
04536     r=CFrogNum
04537     now=CFrogNum
04538     rocket=CRocket
04539     hit_wall=CFrogNum
04540   |
04541   'Ask nroot to get off his ass and do this autoamticaly'. 
04542     w _ #world .
04543     now _ CFrogTime now asSeconds.
04544   
04545     health <= 0 ifTrue: [
04546       state = 'Dead' ifTrue: [
04547         ^ 0
04548       ].
04549       w sweepSoundForTime: 1000 withMin: 30 withMax: 20 .
04550       animation_start_tS _ CFrogTime now asSeconds .
04551       animation_no_repeat _ 1 .
04552         template _ w getThingTemplate: 'CCyberPoop/Dead'.
04553       state _ 'Dead' .
04554       self die .
04555       ^ 0 
04556     ] .
04557   
04558     state = 'PrepareFire' ifTrue: [
04559       angle _ (target->x - x) arg: (target->y - y) .
04560       now > (state_start_tS + 1.) ifTrue: [
04561         state _ 'Fire' .
04562         animation_no_repeat _ 0 .
04563         animation_start_tS _ now .
04564         template _ w getThingTemplate: 'CCyberPoop/Fire'.
04565         state_start_tS _ now .
04566       ] ifFalse: [
04567         ^ 1
04568       ].
04569     ].
04570   
04571     state = 'Fire' ifTrue: [
04572       now > (state_start_tS + .5) ifTrue: [
04573         w noiseSoundForTime: 300 withMin: 30 withMax: 40 .
04574         state_start_tS _ now .
04575         angle _ (target->x - x) arg: (target->y - y) .
04576         dist _ ((target->x - x) squared + (target->y - y) squared ) sqrt .
04577         -1 to: 2 do: [:o=CFrogNum | 
04578           rocket _ CRocket new .
04579           rocket->from _ self .
04580           rocket->x _ x .
04581           rocket->y _ y .
04582           rocket->z _ z + .5 .
04583           rocket->angle _ angle + (o * 3.14 / 3) .
04584           rocket->momx _ 20 * rocket->angle cos .
04585           rocket->momy _ 20 * rocket->angle sin .
04586           rocket->momz _ (target->z +.5 - rocket->z ) / dist * 20 . 
04587         ] .
04588         r _ random_generator next .  
04589         ((self canSeeThing: target) and: (r > .333))  ifTrue: [
04590           state _ 'Fire' . 
04591           ^ 1 .
04592         ] ifFalse: [
04593           state _ 'Chase' . 
04594         ] .
04595       ] ifFalse: [
04596         ^ 1 .
04597       ] .
04598     ].
04599   
04600     animation_no_repeat _ 0 .
04601     template _ w getThingTemplate: 'CCyberPoop'.
04602   
04603     (target hasClass: C3DThing) ifFalse: [
04604       target _ self lookForTarget .
04605     ] .
04606     (state = 'Wait' and: target->health > 0) ifTrue: [
04607       (self canSeeThing: target) ifTrue: [
04608         state  _ 'Chase' .
04609         steps_to_walk _ random_generator next * 10 + 5 .
04610         angle _ target->x - x arg: target->y - y .
04611       ] .
04612     ] .
04613   
04614     (target->health <= 0.) ifTrue: [
04615       target _ 0 .
04616       state _ 'Wait'.
04617     ] .
04618   
04619     state = 'Chase' ifTrue: [
04620       steps_to_walk _ steps_to_walk - 1 .
04621       (r < (.5 / 10 ) or: steps_to_walk <= 0 ) ifTrue: [
04622         steps_to_walk _ random_generator next * 10 + 7 .
04623         state _ 'PrepareFire' .
04624         w sweepSoundForTime: 1000 withMin: 50 withMax: 70 .
04625         angle _ (target->x - x) arg: (target->y - y) .
04626         template _ w getThingTemplate: 'CCyberPoop/Fire'.
04627         state_start_tS _ now .
04628         ^ 1 .
04629       ] .
04630     
04631       self wander: 10 withJumpVelocity: .60 withTarget: target .
04632     ] .
04633   
04634 
04635                                   CONSTRUCTOR
04636   
04637   init->*
04638   |
04639     sun=CDayNightStar
04640     moon=CDayNightStar
04641     star=CDayNightStar
04642   |
04643     start_tS _ CFrogTime now asSeconds .
04644     day_length _ 128 .
04645     sun _ CDayNightStar new.
04646     sun->radius _ 200 .
04647     sun->color _ #color_YELLOW .
04648     sun->rot1 _ 3.14 .
04649     sun->rot2 _ 0 .
04650   'Moon is at other side of  sky '.
04651     moon _ CDayNightStar new .
04652     moon->radius _ 150 .
04653     moon->color _ #color_LTGRAY .
04654     moon->rot1 _ 0 .
04655     moon->rot2 _ 0 .
04656   
04657     stars _ #( sun moon) .
04658   
04659   'TODO populate stars'.
04660   
04661     self update .
04662     ^ self
04663   
04664 
04665                                      update
04666   
04667   update->*
04668   |
04669     t=CFrogNum
04670     rot=CFrogNum
04671     rot2=CFrogNum
04672     p=CPlayer
04673     x=CFrogNum
04674     y=CFrogNum
04675     z=CFrogNum
04676     mag=CFrogNum
04677     w=C3DWorldManager 
04678     tmp=CFrogNum
04679     tmp2=CFrogNum
04680     sky_colors=CFrogArray
04681     sky_times=CFrogArray
04682     sky_brights=CFrogArray
04683   |
04684     w _ #world .
04685     p _ w getPlayer .
04686     t _ CFrogTime now asSeconds - start_tS .
04687     rot2 _ 2 * 3.14 * (t / day_length) .
04688   
04689   
04690     sky_colors _ #(#color_BLUE #color_LTBLUE #color_LTCYAN #color_LTCYAN #color_LTBLUE #color_BLUE #color_BLACK #color_BLACK #color_BLACK #color_BLACK #color_BLACK) .
04691     sky_brights _ #(4 6 9 10 6 4 3 2 2 2 3) .
04692   
04693     'Adjust sky_color(Lerp the values)' .
04694     sky_color _ (rot2 / (2 * 3.14) rem: 1) * sky_colors size .
04695   
04696     w->sky_light _ sky_brights at: sky_color .
04697     sky_color _ sky_colors at: sky_color .
04698   
04699     stars do:[:s=CDayNightStar|
04700       tmp _ s->rot1 .
04701       tmp2 _ (s->rot2 - rot2 ).
04702   
04703       x _ tmp sin .
04704       mag _ tmp cos .
04705       z _ tmp2 sin * mag .
04706       y _ tmp2 cos * mag .
04707   
04708       x _ x * 100 .
04709       y _ y * 100 .
04710       z _ z * 100 .
04711   
04712      'Place star relative to player position' .
04713       s->screen_x _ #world pointToScreenXAtX: x * 128 + p->x atY: y * 128 + p->y atZ: z + p->z + .6 .
04714       s->screen_y _ #world pointToScreenYAtX: x * 128 + p->x atY: y * 128 + p->y atZ: z + p->z + .6 .
04715   
04716     ] . 
04717 
04718                                   CONSTRUCTOR
04719   
04720   init | |
04721    ^ self
04722   
04723 
04724                                   CONSTRUCTOR
04725   
04726   init | |
04727     speed _ 3 .
04728     going_back _ 0 .
04729     hit _ #() .
04730   
04731   
04732     color _ #color_LTRED .
04733     thick _ 8 .
04734   
04735    ^ self
04736   
04737 
04738                                      update
04739   
04740   
04741 
04742                                   CONSTRUCTOR
04743   
04744   init->CDoor | |
04745     activated_at _ -1 .
04746     open_duration _ .5 .
04747     speed _ 1 / 2 .
04748     percent _ 1 .
04749     stains _ #() .
04750     ^ self
04751   
04752 
04753                                     activate
04754   
04755   activate->CFrogNum |
04756     activate_other=CFrogBlock
04757     world=C3DWorldManager
04758   |
04759     world _ #world .
04760     activated _ 1 .
04761     
04762     activated_at < 0. ifTrue: [
04763       activated_at _ CFrogTime now asSeconds .
04764       world->doors do:[:d=CDoor|
04765         ((d->x - x) abs < 1.1 and: (d->y - y) abs < 1.1 ) ifTrue: [
04766           d->activated ifFalse: [
04767   'Inherit LOCKed properites of the adjacent door' .
04768   'This is used when update-ing doors to avoid having adjacent doors open again' .
04769             d->small_key _ small_key .
04770             d->big_key _ big_key .
04771             d->tag _ tag .
04772             d activate
04773           ] .
04774         ] .
04775       ] .
04776       ^ 1 .
04777     ].
04778      ^ 0 .
04779   
04780 
04781                                    activateBy
04782   
04783   activateBy: t=C3DThing  ->CFrogNum
04784     |
04785     player=CPlayer
04786     items=CFrogArray 
04787     key=CHandItem
04788     locked=CFrogNum
04789   |
04790     tag ifTrue: [^ 0. ] .
04791     activated ifTrue: [^ 0 . ] .
04792     player _ #world getPlayer .
04793     key _ 0 .
04794     locked _ 0 .
04795   'Not openable except by having an adjacent door open' .
04796     side_door ifTrue: [
04797      ^ 0
04798     ] .
04799     small_key ifTrue: [
04800       locked _ 1 .
04801       items _ player getInventoryItems .
04802       items do: [:i*|
04803         (i->item hasClass: CSmallKey) ifTrue: [
04804           key _ i
04805         ] .
04806       ] .
04807     ]. 
04808     big_key ifTrue: [
04809       locked _ 1 .
04810       items _ player getInventoryItems .
04811       items do: [:i*|
04812         (i->item hasClass: CBigKey) ifTrue: [
04813           key _ i
04814         ] .
04815       ] .
04816     ]. 
04817     locked ifTrue: [
04818       (key hasClass:CUIGridItem) ifTrue: [
04819         self activate ifTrue: [
04820           player removeItem: key .
04821           player displayMessage: 'Unlocked door' .  
04822           ^ 1 .
04823         ] .
04824         ^ 0 .
04825       ] .
04826       small_key ifTrue: [
04827         player displayMessage: 'You need a small key' .  
04828       ] .
04829       big_key ifTrue: [
04830         player displayMessage: 'You need a big ass motherfuckin key' .  
04831       ] .
04832       ^ 0 .
04833     ] ifFalse: [
04834       self activate ifTrue: [
04835        player displayMessage: 'Mpotherfuckiing door opened' .
04836        ^ 1
04837       ] ifFalse: [
04838        ^ 0
04839       ] .
04840     ] .
04841     ^ 0
04842 
04843                                  activateByTag
04844   
04845   activateByTag: what=CFrogNum  ->CFrogNum
04846   |
04847     player=CPlayer
04848   |
04849     activated ifTrue: [^ 0 . ] .
04850     player _ #world getPlayer .
04851     tag = what ifTrue: [
04852       player displayMessage: 'A Door jit fuckin opened' .
04853       self activate .
04854       ^ 1 .
04855     ] .
04856     ^ 0
04857 
04858                                      update
04859   
04860   update->* |
04861     rise_time=CFrogNum
04862     tS=CFrogNum
04863   |
04864     tS _ CFrogTime now asSeconds.
04865     activated_at < 0 ifFalse: [
04866       tS _ tS - activated_at .
04867       rise_time _ height / speed .
04868       tS < rise_time ifTrue: [
04869         percent _ 1 - (tS / rise_time) .
04870         ^ 1 .
04871       ] .
04872       (tag or: (big_key or: small_key)) ifTrue: [
04873         'Dont reopen if we are a locked door ' .
04874          activated_at _ -1 .
04875          percent _ 0 .
04876          ^ 0
04877       ] .
04878       tS > (rise_time + open_duration) ifTrue: [
04879         percent _  ((tS- rise_time - open_duration ) / rise_time) .
04880         percent >= 1. ifTrue: [
04881           activated_at _ -1 .
04882           percent _ 1 .
04883           activated _ 0 .
04884           ^ 0 
04885         ]
04886         ^ 1 .
04887       ]
04888       ^ 1 .
04889     ].
04890     activated_at _ -1 .
04891     ^ 0
04892 
04893                                   CONSTRUCTOR
04894   
04895   init | |
04896    ^ self
04897   
04898 
04899                                       fire
04900   
04901   fire ->* |
04902    w=C3DWorldManager
04903    cur_ts=CFrogNum
04904    wz=CFrogNum
04905    wx=CFrogNum
04906    wy=CFrogNum
04907    dist=CFrogNum
04908    a=CFrogNum
04909    player=CPlayer
04910    tile=C3DPoint
04911    side=C3DPoint
04912   
04913    door=CDoor
04914    |
04915     w _ #world .
04916     cur_ts _ CFrogTime now asSeconds .
04917     timeout < cur_ts ifTrue: [
04918       timeout _ cur_ts + .1 .
04919   
04920       tile _ w screenTile .
04921       side _ w screenTileSide. 
04922       wx _ tile->x + side->x .
04923       wy _ tile->y + side->y .
04924       wz _ tile->z + side->z .
04925   
04926       door _ CDoor new.
04927       door->x _ wx .
04928       door->y _ wy .
04929       door->z _ wz .
04930       door->tag _ tag .
04931       door->speed _ speed .
04932       door->open_duration _ open_duration .
04933       door->act_as_wall _ act_as_wall .
04934       door->height _ height .
04935   
04936       w addDoor: door .
04937   
04938       w->is_client ifTrue: [
04939         #client sendPlaceDoor: door .
04940       ] .
04941     ] .
04942 
04943                                   CONSTRUCTOR
04944   
04945   init ->* |
04946     grid=CUIGrid
04947     item=CUIGridItem
04948     scroll_bars=CUIScrollBars
04949     tile=CTileTemplate
04950     new_texture=CFrogImg
04951     ui_roots=CFrogArray
04952     handled=CFrogNum
04953     old*
04954     inv_item=CWorldEditBlock
04955     n=CUINotification 
04956     array=CFrogArray
04957   
04958     door_height=CFrogNum
04959     small_key=CFrogNum
04960     big_key=CFrogNum
04961     tag_number=CFrogNum
04962     button1=CFrogArray
04963     button2=CFrogArray
04964     button3=CFrogArray
04965     button4=CFrogArray
04966     button5=CFrogArray
04967     list=CUIList
04968   
04969     update_buttons=CFrogBlock
04970   
04971     ask_num=CFrogBlock
04972     text_input=CUITextBar
04973   
04974     group=CUIBackground
04975     
04976     hand_item=CDoorItem
04977     act_as_tile=CFrogNum
04978   
04979     popup=CTextPopup
04980   |
04981     ask_num _ [:t=CFrogStr :result=CFrogBlock|
04982       popup _ CUITextPopup new .
04983       popup->title _ t .
04984       popup->cb _ [:s=CFrogStr|
04985         result value: s asInteger
04986       ] .
04987       popup run .
04988     ].
04989   
04990     'Draw world in background' .
04991     draw_it_name _ 'Draw3DWorld' .
04992   
04993   
04994     update_buttons _ [
04995       button5 _ #(
04996         ('Add to Inventory')
04997         [
04998           hand_item _ CDoorItem new .
04999           hand_item->speed _ 1 . 'TODO'.
05000           hand_item->open_duration _ 2 . 'TODO'.
05001           hand_item->tag _ tag_number .
05002           hand_item->small_key _ small_key .
05003           hand_item->big_key _ big_key .
05004           hand_item->height _ door_height .
05005           hand_item->gr _ tile->wall_texture .
05006           hand_item->act_as_wall _ tile->tile_idx .
05007    
05008           item _ CUIGridItem  new .
05009           item->graphics _ tile->wall_texture .
05010           item->item _ hand_item .
05011           item->cnt _ tag_number .
05012           item onLeftUp: [
05013             #world getPlayer selectItem: hand_item .
05014           ] .
05015   
05016           #world getPlayer addInventoryItem: item .
05017         ]
05018       ) .
05019       button1 _ #(
05020         ('Door Height(' , door_height printString,')')
05021         [
05022           ask_num value: 'Door Height' value:  [:n=CFrogNum|
05023             door_height _ n .
05024             update_buttons value .
05025           ]
05026         ]
05027       ) .
05028   
05029       button2 _ #(
05030         ('Tag Number(' , tag_number printString,')')
05031         [
05032           ask_num value: 'Tag Number' value:  [:n=CFrogNum|
05033             tag_number _ n .
05034             update_buttons value .
05035           ]
05036         ]
05037       ) .
05038   
05039   
05040   
05041       small_key ifTrue: [
05042         button3 _ #(
05043           'Disable Small Key'
05044           [
05045             small_key _ small_key not.
05046             update_buttons value.
05047           ]
05048         ).
05049       ] ifFalse: [
05050         button3 _ #(
05051           'Enable Small Key'
05052           [
05053             small_key _ small_key not.
05054             update_buttons value.
05055           ]
05056         ).
05057       ] .
05058   
05059       big_key ifTrue: [
05060         button4 _ #(
05061           'Disable Big Key'
05062           [
05063             big_key _ big_key not.
05064             update_buttons value.
05065           ]
05066         ).
05067       ] ifFalse: [
05068         button4 _ #(
05069           'Enable Big Key'
05070           [
05071             big_key _ big_key not.
05072             update_buttons value.
05073           ]
05074         ).
05075       ] .
05076   
05077   
05078   
05079       group removeChild: list .
05080       list _ CUIList new: #(button5 button1 button2 button3 button4) .
05081       group addChild: list .
05082     ].
05083   
05084     on_init _ [
05085       n _ CUINotification new: 'Click Block to For Door Menu' .
05086       n setIcon: 'Icons/Button' . 
05087       n addToPoopidexCategory: 'Controls/DoorEdit' withDescription: 'Click a block in the door shell to make a new door'.
05088       #ms_grabbed _ 0 .
05089       #ui_root _ CUIElem new .
05090       ui_roots _ #(#ui_root) .'I make a stack of UIs that are POPed' .
05091       #ui_root show .
05092       #ui_root -> x _ 0 .
05093       #ui_root -> y _ 0 .
05094       #ui_root -> sz_x _ 640 .
05095       #ui_root -> sz_y _ 480 .
05096       scroll_bars _ CUIScrollBars new .
05097       scroll_bars ->x _ 10 .
05098       scroll_bars ->y _ 10 .
05099       scroll_bars ->sz_y _ 460 .
05100       scroll_bars ->sz_x _ 620 .
05101       scroll_bars->bg_color _ #color_DKGRAY .
05102       grid _ CUIGrid new .
05103       grid setWidth: 16 withHeight: 16 .
05104       1 to: 256 do:[:b=CFrogNum |
05105         item _ CUIGridItem new .
05106         tile _ (#world -> tile_templates at: b) .
05107         item->graphics _  tile->wall_texture  .
05108         (tile hasClass: CTileTemplate) ifTrue: [
05109           item -> item _ tile  .
05110         ] ifFalse: [
05111           item -> item _ b .
05112         ] .
05113         item->cnt _ b .
05114         item onLeftUp: [:elem=CUIGridItem |
05115           tile _ elem -> item .
05116           (tile hasClass: CTileTemplate) ifTrue: [
05117   
05118             act_as_tile _ tile->tile_idx .
05119             tag_number _ 0 .
05120             small_key _ 0 .
05121             big_key _ 0 .
05122             door_height _ 2 .
05123   
05124             'Remove old group ' .
05125             group _ CUIBackground new .
05126             ui_roots add: group .
05127             #ui_root _ group .
05128             group-> bg_color _ #color_DKGRAY .
05129             group setHeight: 300 .
05130             group setWidth: 200 .
05131             group->x _ 640 / 2 - (group->sz_x / 2) .
05132             group->y _ 480 / 2 - (group->sz_y / 2) .
05133           
05134             update_buttons value .
05135           ] .
05136   
05137         ] .
05138         grid addItem: item .
05139       ] .
05140   
05141       #ui_root addChild: scroll_bars .
05142       scroll_bars addChild: grid .
05143       grid->x _ 10 .
05144       grid->y _ 10 .
05145     ] .
05146   
05147     on_event _ [:v=CUIEvent |
05148       handled _ 0 .
05149       v->type = 'KeyDown' ifTrue: [
05150         v->m1 = 27 ifTrue: [
05151           'ESC '.
05152           ui_roots size <= 1 ifTrue: [
05153             exited _ 1 .
05154             handled _ 1 . 
05155           ] ifFalse: [
05156   'POP the ui menus until nothing left to pop' .
05157             ui_roots remove: (ui_roots at: ui_roots size - 1) .
05158             #ui_root _ ui_roots at: ui_roots size - 1 .
05159             handled _  1.  
05160           ] .
05161         ] .
05162       ] .
05163       handled ifFalse: [
05164         #ui_root sendEventToUI: v .
05165       ].
05166     ] .
05167     ^ self
05168   
05169   
05170 
05171                                       fire
05172   
05173   fire ->* |
05174    w=C3DWorldManager
05175    cur_ts=CFrogNum
05176    wz=CFrogNum
05177    wx=CFrogNum
05178    wy=CFrogNum
05179    dist=CFrogNum
05180    a=CFrogNum
05181    player=CPlayer
05182    tile=C3DPoint
05183    side=C3DPoint
05184    |
05185     w _ #world .
05186     cur_ts _ CFrogTime now asSeconds .
05187     timeout < cur_ts ifTrue: [
05188       timeout _ cur_ts + .1 .
05189   
05190       tile _ w screenTile .
05191       side _ w screenTileSide. 
05192       wx _ tile->x + side->x .
05193       wy _ tile->y + side->y .
05194       wz _ tile->z + side->z .
05195   
05196       w setTile: tile_idx atX: wx atY: wy atZ: wz.
05197   
05198       w->is_client ifTrue: [
05199         #client sendPlaceDoor: tile_idx atX: wx atY: wy atZ: wz 
05200       ] .
05201     ] .
05202 
05203                                   CONSTRUCTOR
05204   
05205   init-> CEggplantMan | |
05206     #world addThing: self .
05207     random_generator _ CFrogRandom new .
05208     template _ #world getThingTemplate: 'CEggplantMan/Normal' .
05209     template->radius _ 128 .
05210     health _ 200 .
05211     state _ 'Normal' .
05212     ^ self
05213   
05214 
05215                                     animate
05216   
05217   animate ->*
05218   ||
05219     self updateGrab
05220 
05221                                    damageFrom
05222   
05223   damage: d=CFrogNum from: t=C3DThing ->*
05224   ||
05225     state = 'Grab' ifTrue: [
05226       state = 'Grab3' .
05227     ] .
05228   
05229     target _ t 
05230 
05231                                   grabbedThing
05232   
05233   grabbedThing ->C3DThing
05234   |
05235     d=CFrogNum  
05236     d2=CFrogNum
05237     a=CFrogNum
05238     xx=CFrogNUm
05239     yy=CFrogNum
05240     zz=CFrogNum
05241     things=CFrogArray
05242     best_thing=CFrogThing
05243     best_dist=CFrogNum
05244   |
05245     (left_arm hasClass: C3DLine) ifFalse: [
05246       ^ 0 .
05247     ] .
05248     d _ ((left_arm->x - x ) squared +  (left_arm->y - y) squared ) sqrt .
05249     things _ #world getThingsInRadiusFromX: x fromY: y withRadius: d + 128 .
05250     things _ things select:[:t=C3DThing|
05251       ((left_arm hitsThing: t withRadius: 190 ) and: t ~= self) and: t->health > 0
05252     ] .
05253   
05254     best_thing _ 0 .
05255     best_dist _ d * 2 + 256 .
05256     things do: [:t=C3DThing|
05257       d _ ((t->x - x ) squared +  (t->y - y) squared + (t->z - z * 128)squared ) sqrt .
05258       best_dist > d ifTrue: [
05259         best_thing _ t .
05260         best_dist _ d .
05261       ] .
05262     ] .
05263   
05264     ^ best_thing .
05265 
05266                                      update
05267   
05268   update->* |
05269     w=C3DWorldManager
05270     p=CPlayer
05271     tS=CFrogNum 
05272     speed=CFrogNum
05273   |
05274     speed _ 16 .
05275   
05276   
05277     tS _ CFrogTime now asSeconds.
05278     w _ #world .
05279   
05280   
05281     health <= 0 ifTrue: [
05282       state _ 'Dead' .
05283       animation_no_repeat _ 1 .   
05284       animation_start_tS _ tS .
05285       template _ w getThingTemplate: 'CEggplantMan/Dead' .
05286       self die .
05287     ] .
05288   
05289     (state = 'Normal' or: state = 'Idle' ) ifTrue: [
05290       template _ w getThingTemplate: 'CEggplantMan/Normal' .
05291       animation_no_repeat _ 0 .   
05292       ((target hasClass: C3DThing) or: target->health < 0 ) ifFalse: [
05293         target _ self lookForTarget .
05294       ]
05295     ] .
05296     (target hasClass: C3DThing) ifFalse: [
05297       ^ 0
05298     ] .
05299   
05300   
05301     state = 'Normal' ifTrue: [
05302       template _ w getThingTemplate: 'CEggplantMan/Normal' .
05303       animation_no_repeat _ 0 .
05304       state _ 'Chase' .
05305       steps_to_walk _ random_generator next * 8 + 4 .
05306     ].
05307   
05308     state = 'Chase' ifTrue: [
05309       self wander: speed withJumpVelocity: .55 withTarget: target .
05310       steps_to_walk  _ steps_to_walk - 1 .
05311       steps_to_walk > 0 ifFalse: [
05312       (self canSeeThing: target)  ifTrue: [
05313           state _ 'Grab' .
05314           template _ w getThingTemplate: 'CEggplantMan/Attack' .
05315           animation_start_tS _ tS .
05316           animation_no_repeat _ 1 .   
05317           state_start_tS _ tS .
05318         ] ifFalse: [
05319           state _ 'Normal' .
05320         ]
05321       ].
05322     ] .
05323   
05324 
05325                                    updateGrab
05326   
05327   updateGrab->CFrogNum
05328   |
05329     normal=CFrogNum
05330     tx=CFrogNum
05331     ty=CFrogNum
05332     tz=CFrogNum
05333     target_d=CFrogNum
05334     d=CFrogNum
05335     a=CFrogNum
05336     a2=CFrogNum
05337     rel_tS=CFrogNum
05338     w=C3DWorldManager
05339     final=CFrogBlock
05340     thrust_speed=CFrogNum
05341     hit_thing=CFrogBlock
05342     thing=C3DThing
05343   |
05344     #world removeThing: left_hand .
05345     #world removeThing: right_hand .
05346   
05347   
05348     hit_thing _ [:target=C3DThing|
05349      'We successfully? grabbed the target' .
05350       state _ 'Grab3' .
05351       state_start_tS _ CFrogTime now asSeconds .
05352   
05353       'Damage the target' .
05354       target damage: 25 from: self .
05355       'Thrust target towards self' .
05356       a _ a + 3.14 .
05357       thrust_speed _ random_generator next * 5 * 128 + 256 / 15  .
05358       target->momx _ target->momx + (thrust_speed * a2 cos abs * a cos ) . 
05359       target->momy _ target->momy + (thrust_speed * a2 cos abs * a sin ) . 
05360       target->momz _ target->momz + (thrust_speed * a2 sin / 128) + .6 . 
05361     ] .
05362     final _ [
05363       normal _ angle + (3.14 / 2) .
05364   
05365       left_arm  _ C3DLine new .
05366       left_arm->thick _ 8 .
05367       left_arm->color _ #color_PURPLE .
05368   
05369       left_arm->x0 _ x + (32 * normal cos) .
05370       left_arm->y0 _ y + (32 * normal sin) .
05371       left_arm->z0 _ z + .5 . 
05372       left_arm->x _ tx + (32*normal cos ) .
05373       left_arm->y _ ty + (32*normal sin ) .
05374       left_arm->z _ tz .
05375   
05376       normal _ angle - (3.14 / 2) .
05377   
05378       right_arm  _ C3DLine new .
05379       right_arm->thick _ 8 .
05380       right_arm->color _ #color_PURPLE .
05381   
05382       right_arm->x0 _ x + (32 * normal cos) .
05383       right_arm->y0 _ y + (32 * normal sin) .
05384       right_arm->z0 _ z + .5 . 
05385       right_arm->x _ tx + (32*normal cos ) .
05386       right_arm->y _ ty + (32*normal sin ) .
05387       right_arm->z _ tz .
05388   
05389       right_hand _ C3DThing new.
05390       right_hand->template _ #world getThingTemplate: 'CEggplantMan/Hand' .
05391       right_hand->x _ right_arm->x .
05392       right_hand->y _ right_arm->y .
05393       right_hand->z _ right_arm->z .
05394       right_hand->floating _ 1 .
05395       right_hand->angle _ angle .
05396   
05397       left_hand _ C3DThing new.
05398       left_hand->template _ #world getThingTemplate: 'CEggplantMan/Hand' .
05399       left_hand->x _ left_arm->x .
05400       left_hand->y _ left_arm->y .
05401       left_hand->z _ left_arm->z .
05402       left_hand->floating _ 1 .
05403       left_hand->angle _ angle .
05404   
05405     ].
05406   
05407     w _ #world .
05408   
05409     rel_tS _ CFrogTime now asSeconds  - state_start_tS .
05410   
05411     state = 'Grab' ifTrue: [
05412       target_d _ ((target->x - x / 128 ) squared + (target->y - y / 128 ) squared) sqrt.
05413       d _ target_d min: rel_tS * 6  .
05414       a _ target->x - x arg: target->y - y .
05415       a2 _ target_d arg: (target->z - z). 
05416       tx _ d * a cos * 128 + x .
05417       ty _ d * a sin * 128 + y .
05418       tz _ d / target_d * (target->z - z ) + z + .5 .
05419       angle _ a .
05420   
05421       thing _ self grabbedThing .
05422       (thing hasClass: C3DThing) ifTrue: [
05423         hit_thing value: thing .
05424         ^ 1 .
05425       ] .
05426   
05427       final value .
05428   
05429       d >= target_d ifTrue: [
05430         (target hasClass: C3DThing) ifTrue: [
05431           hit_thing value: target.
05432         ] .
05433         state _ 'Grab3' .
05434         state_start_tS _ CFrogTime now asSeconds .
05435       ] .
05436   
05437       (self canSeeThing: target ) ifFalse: [
05438         'Cant see go back' .
05439         state _ 'Grab3' .
05440         state_start_tS _ CFrogTime now asSeconds .
05441       ] .
05442   
05443       (w getTileAtX: tx / 128 atY: ty / 128 atZ: tz ) ifTrue: [
05444         'Hit a wall ' .
05445         state _ 'Grab3' .
05446         state_start_tS _ CFrogTime now asSeconds .
05447       ] .
05448       ^ 1 .
05449     ] .
05450   
05451   
05452     state = 'Grab3' ifTrue: [
05453       'Return Arms to eggplant man' .
05454   
05455       tx _ left_arm->x + right_arm->x / 2 . 
05456       ty _ left_arm->y + right_arm->y / 2 . 
05457       tz _ left_arm->z + right_arm->z / 2 . 
05458       angle _ tx - x arg: ty - y .
05459   
05460       target_d _ ((tx - x / 128) squared + (ty - y /128) squared + (tz - z - .5 ) squared ) sqrt .
05461   
05462       d _ target_d - (10 / 30 ) max: 0.1 .
05463   
05464       tx _ (tx - x) * (d / target_d ) + x .
05465       ty _ (ty - y) * (d / target_d ) + y .
05466       tz _ (tz - z - .5 ) * (d / target_d ) + z + .5 .
05467   
05468       d <= 0.11 ifTrue: [
05469         left_arm _ 0 .
05470         right_arm _ 0 .
05471         left_hand _ 0 .
05472         right_hand _ 0 .
05473         state _ 'Normal' .
05474         ^ 0 .
05475       ] .
05476   
05477       final value .
05478       ^ 1 .
05479     ] .
05480   
05481   
05482   
05483     left_arm _ 0 .
05484     right_arm _ 0 .
05485     left_hand _ 0 .
05486     right_hand _ 0 .
05487   
05488     ^ 0 .
05489 
05490                                   CONSTRUCTOR
05491   
05492   init | |
05493     reasms _ #() .
05494     synonyms _ CFrogDictionary new .
05495     hello _ 'Hello!' .
05496     quit _ 'Quit' .
05497     stack _ #() .
05498     cur_flags _ #() .
05499    ^ self
05500   
05501 
05502                                     Message
05503   
05504   message: str=CFrogStr -> * |
05505     sub*
05506     reduce=CFrogBlock
05507     res*
05508     clone=CFrogArray
05509   |
05510     reduce _ [:result* |
05511       (result hasClass: CFrogStr) ifTrue: [
05512         ^ result 
05513       ] .
05514       (result hasClass: CEliza) ifTrue: [
05515         stack remove result .
05516         stack add: result .
05517         ^ result getHello copy
05518       ] .
05519       (result hasClass: CFrogBlock) ifTrue: [
05520          result _ result value .
05521          (result hasClass: CFrogStr ) ifTrue: [
05522             ^ result
05523          ].
05524          (result hasClass: CFrogArray ) ifTrue: [
05525             sub _ CEliza makeResponsesFromArray: result .
05526             stack add: sub .
05527             ^ sub getHello copy
05528          ] .
05529       ] .
05530     ] .
05531     clone _ stack copy .
05532     stack size ifTrue: [
05533       0 to: stack size do: [:idx=CFrogNum|
05534         'Most recent are at end '.
05535         sub _ clone at: (clone size - 1 - idx)  .
05536         sub setSynonyms: self getSynonyms .
05537         res _ sub message0: str .
05538         reduce value: res .
05539       ]
05540     ] .
05541     res _ self message0: str .
05542     reduce value: res .
05543     ^ 0 
05544 
05545                                     addReasm
05546   
05547   addReasm: r=CElizaReasm ->*  ||
05548     reasms add: r 
05549 
05550                                  addSynonymFor
05551   
05552   addSynonym: s=CFrogStr for: f=CFrogStr ->* ||
05553     synonyms at: s put: f copy 
05554 
05555                                     getFocus
05556   
05557   getFocus ->CFrogNum ||
05558     ^ focus
05559 
05560                                     getHello
05561   
05562   getHello->CFrogStr || ^ hello
05563 
05564                                     getQuit
05565   
05566   getQuit ->CFrogStr || ^ quit
05567 
05568                                    getSynonym
05569   
05570   getSynonym: word=CFrogStr ->CFrogStr |s=CFrogStr|
05571     s _  synonyms at: word .
05572     ( s hasClass: CFrogStr ) ifTrue: [
05573       ^ s
05574     ].
05575     ^ word 
05576 
05577                                   getSynonyms
05578   
05579   getSynonyms ->CFrogDictionary  || ^ synonyms
05580 
05581                                  inherit_quest
05582   
05583   inheritOther: other=CEliza ->*
05584   |
05585     has_parts=CFrogArray
05586   |
05587     has_parts _ reasms collect: [:r=CElizaReasm| r -> parts] .
05588     other->reasms do: [:r=CElizaReasm|
05589       (has_parts has: r->parts) ifFalse: [
05590         reasms add: r
05591       ].
05592     ] .
05593   
05594 
05595                                     message0
05596   
05597   message0: str=CFrogStr ->* |
05598      player=CPlayer
05599      valid=CFrogArray
05600      split=CFrogArray 
05601      tmp=CFrogStr
05602      choose=CElizaReasm
05603      choose2=CElizaReasm
05604      wildcards=CFrogArray
05605      best_match_len=CFrogNum
05606      best_flag_cnt=CFrogNum
05607      set=CFrogArray
05608      score=CFrogNum
05609      accept=CFrogBlock
05610      ret*
05611   |
05612     player _ #world getPlayer .
05613     tmp _ '' .
05614     split _ #() .
05615     str do: [:ch* | 
05616       ch isAlphaNumeric ifTrue: [
05617         tmp add: ch 
05618       ] ifFalse: [
05619         tmp size ifTrue: [
05620           split add: (self getSynonym: tmp copy )
05621         ] .
05622         tmp _ '' .
05623       ]
05624     ] .
05625     tmp size ifTrue: [
05626       split add: (self getSynonym: tmp copy )
05627     ] .
05628   
05629     valid _ reasms select: [:r=CElizaReasm | 
05630       (r matchWords: split ) and: ( r acceptsFlags: player->quest_flags )
05631     ] .
05632   
05633     valid size ifFalse: [
05634       ^ 0 .
05635     ] .
05636   
05637   
05638     best_match_len _ 0 .
05639     set _ valid collect: [:x=CElizaReasm|
05640       wildcards _ #() .
05641       x matchWords: split putWildcardsIn: wildcards .
05642       best_match_len _ best_match_len max: wildcards size .
05643       score _ x acceptsFlags: cur_flags .
05644       'See below note' . 
05645       #( (x) (wildcards) (score) )
05646     ] .
05647     
05648   
05649     set _ set select:[:x=CFrogArray|
05650        (x at: 1) size = best_match_len
05651     ] .
05652   
05653   'Pass 2,use one with best matched flags' .
05654     best_flag_cnt _ 0 .
05655     set do: [:x=CFrogArray|
05656   'Accept flags returns 1 + number of matched flags'.
05657   'I want the most matched flags' .
05658       best_flag_cnt _ best_flag_cnt max: (x at: 2).
05659     ] .
05660   
05661     set _ set select:[:x=CFrogArray|
05662        (x at: 2) = best_flag_cnt
05663     ] .
05664   
05665     '???' .
05666     set size ifFalse: [^ 0 ] .
05667   
05668   's3' show .
05669     set size show.
05670   
05671     '#(CElizaReasm wildcards score )' .
05672     'Pick lowest frequnecy response' .
05673     split _  set at: (CFrogRandom new next * set size - .001) . 
05674     choose _ split at: 0 .
05675     set do: [:e*|
05676       choose2 _ e at: 0 .
05677   'cc2' show .
05678       choose->freq show .
05679       choose2->freq show .
05680       choose->freq > choose2->freq ifTrue: [
05681         choose _ choose2 .
05682         split _ e 
05683       ] .
05684     ] .
05685   
05686   
05687     accept _ [
05688       choose->add_flags do: [:add=CFrogStr|
05689         (player->quest_flags has: add) ifFalse: [
05690           player->quest_flags add: add copy
05691         ] .
05692       ] .
05693       choose->remove_flags do: [:rem=CFrogStr|
05694         player->quest_flags remove: rem 
05695       ] .
05696       (choose->give_item_class hasClass: CFrogClass) ifTrue: [
05697         choose->give_item_class new
05698       ].
05699     ] .
05700   
05701   'Choose result before adding quest_seen_responses' .
05702   
05703     ret _ choose reassemble: (split at: 1) .
05704   
05705     (choose->global_response_name hasClass: CFrogStr) ifTrue: [
05706       (player->quest_seen_responses has: choose->global_response_name ) ifFalse: [
05707         player->quest_seen_responses add: choose->global_response_name copy .
05708         accept value .
05709       ]
05710     ] ifFalse: accept .
05711   
05712     ^ ret .
05713   
05714 
05715                                     setFocus
05716   
05717   setFocus: f=CFrogNum ||
05718     focus _ f 
05719 
05720                                     setHello
05721   
05722   setHello: str=CFrogStr ->* ||
05723     hello _ str copy 
05724 
05725                                     setQuit
05726   
05727   setQuit: s=CFrogStr ->* ||
05728     quit _ s copy 
05729 
05730                                   setSynonyms
05731   
05732   setSynonyms:s=CFrogDictionary  ||
05733     synonyms _ s 
05734 
05735                                   CONSTRUCTOR
05736   
05737   init | |
05738     add_flags _ #() .
05739     remove_flags _ #() .
05740     need_flags _ #() .
05741     freq _ 0 .
05742     goto_text _ '' .
05743     parts _ #() .
05744    ^ self
05745   
05746 
05747                                   acceptsFlags
05748   
05749   acceptsFlags: flags=CFrogArray ->CFrogNum |
05750   |
05751     'Returns 1 + accept acount' .
05752     need_flags do:[:str=CFrogStr|
05753       (flags has: str) ifFalse: [
05754         ^ 0 
05755       ]
05756     ] .
05757     ^ 1 + need_flags size
05758   
05759 
05760                                   getGotoText
05761   
05762   getGotoText ->CFrogStr ||
05763     ^ goto_text
05764 
05765                                  initFromString
05766   
05767   initFromString: str=CFrogStr ->* |
05768     split=CFrogArray
05769     tmp=CFrogStr
05770   |
05771     split _ #() .
05772     tmp _ '' .
05773     str do: [:ch* | 
05774       ch isWhitespace ifTrue: [
05775         tmp size ifTrue: [
05776           split add: tmp copy
05777         ] .
05778         tmp _ '' .
05779       ] ifFalse: [
05780         tmp add: ch 
05781       ]
05782     ] .
05783     tmp size ifTrue: [
05784       split add: tmp copy
05785     ] .
05786     parts _ split 
05787 
05788                                    matchWords
05789   
05790   matchWords: array=CFrogArray putWildcardsIn: result=CFrogArray ->*|
05791     wi=CFrogNum
05792     next=CFrogStr
05793     wildcard=CFrogArray 
05794     |
05795     wi _ 0 .
05796     0 to: parts size do: [:idx=CFrogNum | 
05797       ( parts at: idx ) = '*' ifTrue: [ 
05798         wildcard _ #() .
05799         ( idx + 1 < parts size ) ifTrue: [
05800           next _ parts at: idx + 1 .
05801           [( array at: wi ) uppercase ~= next uppercase and: wi < array size ] whileTrue: [
05802             wildcard add: ( array at: wi ) copy .
05803             wi _ wi + 1 .
05804           ]
05805         ] ifFalse: [
05806           [ wi < array size ] whileTrue: [
05807             wildcard add: ( array at: wi ) copy .
05808             wi _ wi + 1 .
05809           ]
05810         ] .
05811         result add: wildcard .
05812       ] ifFalse: [
05813         wi >= array size ifTrue: [^ 0 ] .
05814         ( array at: wi ) uppercase = (parts at: idx) uppercase ifTrue: [
05815           wi _ wi + 1 .
05816         ] ifFalse: [
05817           ^ 0
05818         ]
05819       ]
05820     ] .
05821   'pass ' show .
05822     ^ 1 
05823   
05824 
05825                                   matchWords0
05826   
05827   matchWords: array=CFrogArray ->* ||
05828     ^ self matchWords: array putWildcardsIn: #().
05829 
05830                                   modifyFlags
05831   
05832   modifyFlags: flags=CFrogArray ->* |
05833   |
05834     add_flags do:[:str=CFrogStr |
05835       flags add: str copy 
05836     ] .
05837     remove_flags do:[:str=CFrogStr |
05838       flags remove: str 
05839     ] .
05840 
05841                                    reassemble
05842   
05843   reassemble: wildcards=CFrogArray ->* |
05844     ret*
05845     cumsum=CFrogStr 
05846     replace=CFrogBlock 
05847     found_at=CFrogNum
05848     result*
05849     player=CPlayer
05850   |
05851     freq _ freq + 1 .
05852   
05853     player _ #world getPlayer .
05854     result _ first_result . 
05855     (player->quest_seen_responses has: global_response_name) ifTrue: [
05856        result _ again_result .
05857     ] .
05858     result show .
05859   
05860   
05861     (result hasClass: CFrogArray ) ifTrue: [
05862       ret _ (result at: (result size * CFrogRandom new next rem: result size )).
05863     ] ifFalse: [
05864       ret _ result.
05865     ] .
05866     (ret hasClass: CEliza) ifTrue: [
05867       ^ ret 
05868     ] .
05869     ret _ ret copy .
05870     replace _ [:from=CFrogStr :with=CFrogStr |
05871       found_at _ (ret indexOf: from ) .
05872       found_at >= 0 ifTrue: [
05873         ret _ (ret copyFrom: 0 to: found_at ) , with , (
05874           ret copyFrom: found_at + from size to: ret size 
05875         )
05876       ]
05877     ].
05878     0 to: wildcards size do: [:idx* |
05879       cumsum _ '' .
05880       (wildcards at: idx) do:[:s=CFrogStr| 
05881         cumsum  size ifTrue: [
05882           cumsum _ cumsum , ' ' , s
05883         ]  ifFalse: [
05884           cumsum _ cumsum , s 
05885         ]
05886       ] . 
05887       replace
05888         value: ('(' ,  (idx + 1) printString , ')')
05889         value: cumsum
05890     ] .
05891   
05892   
05893     ^ ret
05894   
05895 
05896                                   setAddFlags
05897   
05898   setAddFlags: nf=CFrogArray ->* ||
05899     add_flags _ nf 
05900 
05901                                 setIsValidBlock
05902   
05903   setIsValidBlock: bl=CFrogBlock ->* || is_valid_block _ bl .
05904 
05905                                   setNeedFlags
05906   
05907   setNeedFlags: nf=CFrogArray ->* ||
05908     need_flags _ nf 
05909 
05910                                setOnCompleteBlock
05911   
05912   setOnCompleteBlock: bl=CFrogBlock ->* || on_complete_block _ bl
05913 
05914                                  setRemoveFlags
05915   
05916   setRemoveFlags: nf=CFrogArray ->* ||
05917     remove_flags _ nf 
05918 
05919                                    setResult
05920   
05921   setResult:r=CFrogStr ->* ||
05922     first_result _ r 
05923 
05924                                   CONSTRUCTOR
05925   
05926   init | |
05927     self setGraphics: 'GR/Wand' .
05928     max_ammo _ 0 . 
05929     ammo _ 1 .
05930     x _ 0 .
05931     y _ 300 .
05932     xoff _ 0 .
05933     yoff _ 0 .
05934     timeout _ 0 .
05935     inventory_item _ CUIGridItem new .
05936     inventory_item setGraphics: 'GR/Wand' .
05937     inventory_item setCount: ammo .
05938     inventory_item setItem: self .
05939     inventory_item ->name _
05940   'Enemy Editor
05941   Change properties of enemy 
05942   Such as Quests,tag number,drop item
05943   ' .
05944     inventory_item onLeftUp: [
05945       #world getPlayer selectItem: self .
05946     ] .
05947     #world getPlayer addInventoryItem: inventory_item .
05948     ^ self
05949   
05950 
05951                                       fire
05952   
05953   fire->*
05954   |
05955     p=CPlayer
05956     best_thing=C3DThing
05957   |
05958     p _ #world getPlayer .
05959     best_thing _ p bestTargetAtAngle: p->angle .
05960     (best_thing hasClass: C3DThing) ifTrue: [
05961       ( CEnemyEditShell new: best_thing) run 
05962     ] .
05963 
05964                                   CONSTRUCTOR
05965   
05966   init:t=C3DThing ->* |
05967     ask_num=CFrogNum
05968     popup=CUITextPopup
05969     ui_roots=CFrogArray
05970     handled=CFrogNum
05971     list=CUIList
05972     pairs=CFrogArray 
05973     sorted=CFrogArray 
05974   
05975     makeui=CFrogBlock
05976     regen=CFrogNum
05977   |
05978     'Draw world in background' .
05979     draw_it_name _ 'Draw3DWorld' .
05980   
05981   
05982     ask_num _ [:title=CFrogBlock :cb=CFrogBlock |
05983       popup _ CUITextPopup new .
05984       popup->title _ title .
05985       popup->cb _ [:s=CFrogStr|
05986         cb value: s asInteger
05987       ] .
05988       popup run .
05989     ].
05990   
05991     makeui _ [
05992       #ui_root _ CUIScrollBars new .
05993       #ui_root->bg_color _ #color_LTGRAY .
05994       #ui_root->sz_x _ 600 .
05995       #ui_root->sz_y _ 480 .
05996       #ui_root->x _ 40 . 
05997       #ui_root->y _ 40 . 
05998   
05999       list _ CUIList new: #(
06000         #(('Set Tag number:', t->activate_tag printString) [
06001           ask_num value: 'Tag number' value: [:v=CFrogNum |
06002             t->activate_tag _ v .
06003             regen _ 1 .
06004           ]
06005         ])
06006         #(('Set/Edit Quest:',t->chat_bot_name) [
06007            t->chat_bot_name _ #world selectQuest .
06008            t->chat_bot _ CEliza newFromBlob: t->chat_bot_name.
06009            regen _ 1 .
06010         ])
06011         #(('Drop Thing:',t->drop_thing asString) [
06012            pairs _ #(
06013              #('Drop Nothing' [
06014                 t->drop_thing _ 0 .
06015                 regen _ 1 .
06016              ])
06017            ).
06018            sorted _#world->thing_templates keys collect: [:k=CFrogStr|
06019              #((k copy) [
06020                 t->drop_thing _ CFrogClass fromString: k .
06021                 regen _ 1 .
06022              ])
06023            ].
06024   
06025            sorted sort: [:a* :b*|
06026                a first compare: b first
06027            ].
06028            sorted _ sorted reject: [:p*|
06029              0 <  (p first indexOf: '/') .
06030            ] .
06031            pairs addAll: sorted .
06032            #ui_root->bg_color _ #color_LTGRAY .
06033            #ui_root->sz_x _ 600 .
06034            #ui_root->sz_y _ 480 .
06035            #ui_root->x _ 40 . 
06036            #ui_root->y _ 40 . 
06037            #ui_root->sub_elems add: (CUIList new: pairs).
06038            ui_roots add: #ui_root .
06039   
06040            list _ CUIList new: pairs .
06041            #ui_root addChild: list .
06042   
06043         ])
06044       ).
06045   
06046       #ui_root addChild: list .
06047       ui_roots _ #(#ui_root).
06048     ] .
06049   
06050   
06051     on_init _ [
06052       ui_roots _ #() .
06053       #ms_grabbed _ 0 .
06054   
06055       makeui value .
06056     ] .
06057   
06058     on_event _ [:v=CUIEvent |
06059       handled _ 0 .
06060       t show .
06061       regen _ 0 .
06062       v->type = 'KeyDown' ifTrue: [
06063         v->m1 = 27 ifTrue: [
06064           'ESC '.
06065           ui_roots size <= 1 ifTrue: [
06066             exited _ 1 .
06067             handled _ 1 . 
06068           ] ifFalse: [
06069             'POP the ui menus until nothing left to pop' .
06070             ui_roots remove: (ui_roots at: ui_roots size - 1) .
06071             #ui_root _ ui_roots at: ui_roots size - 1 .
06072             handled _  1.  
06073           ] .
06074         ] .
06075       ] .
06076       handled ifFalse: [
06077         #ui_root sendEventToUI: v .
06078       ].
06079       regen ifTrue: [
06080         regen _ 0 .
06081         makeui value .
06082       ]
06083     ] .
06084     ^ self
06085   
06086 
06087                                   CONSTRUCTOR
06088   
06089   init ->CEnergyBall | |
06090     #world addThing: self .
06091     template _ #world getThingTemplate: 'CEnergyBall' .
06092     ^ self
06093 
06094                                   checkExplode
06095   
06096   checkExplode ->CFrogNum |
06097     in_radius=CFrogArray
06098   |
06099     in_radius _ #world getThingsInRadiusFromX: x fromY: y withRadius: 32 .
06100     in_radius do:[:t=C3DThing |
06101       (t->z - z) abs < 1.5 ifTrue: [
06102         t ~= from ifTrue: [
06103           t ->health > 0 ifTrue: [
06104             t damage: 15 from: from .
06105             self explode .
06106             ^ 1 .
06107           ]
06108         ]
06109       ]
06110     ] .
06111     ^ 0 .
06112 
06113                                     explode
06114   
06115   explode->* 
06116   |
06117     things=CFrogArray
06118     dist=CFrogNum
06119   |
06120    things _ #world getThingsInRadiusFromX: x fromY: y withRadius:  32 .
06121     things do:[:t*|
06122       (t->z - z) abs < 1.5 ifTrue: [
06123         t ~= from ifTrue: [
06124           dist _ ((t ->x - x) squared + (t ->y - y ) squared) sqrt .
06125           t damage: (32 - dist)/ 32 * 15 from: from . 
06126         ] 
06127       ]
06128     ] .
06129     #world removeThing: self .
06130 
06131                                   CONSTRUCTOR
06132   
06133   init | |
06134     self setGraphics: 'GR/EnergyGun/Idle' .
06135     max_ammo _ 100 . 
06136     ammo _ 10 .
06137     x _ 0 .
06138     y _ 300 .
06139     xoff _ 0 .
06140     yoff _ 0 .
06141     timeout _ 0 .
06142     inventory_item _ CUIGridItem new .
06143     inventory_item setGraphics: 'GR/EnergyGun/Icon' .
06144     inventory_item setCount: ammo .
06145     inventory_item setItem: self .
06146     inventory_item ->name _
06147   'Engery Gun
06148   Zap some fuckin turds
06149   ' .
06150     inventory_item onLeftUp: [
06151       #world getPlayer selectItem: self.
06152     ] .
06153     #world getPlayer addInventoryItem: inventory_item .
06154     ^ self
06155   
06156 
06157                                     animate
06158   
06159   animate ->* | cur_ts=CFrogNum |
06160     cur_ts _ CFrogTime now asSeconds .
06161     inventory_item setCount: ammo  .
06162     timeout < cur_ts ifTrue: [
06163       anim_no_repeat _ 0 .
06164       self setGraphics: 'GR/EnergyGun/Idle' . 
06165     ]. 
06166 
06167                                       fire
06168   
06169   fire ->* |
06170    cur_ts=CFrogNum
06171    player=CPlayer
06172    w=C3DWorldManager
06173    |
06174     w _ #world .
06175     player _ w getPlayer .
06176     ammo ifTrue: [
06177       cur_ts _ CFrogTime now asSeconds .
06178       timeout < cur_ts ifTrue: [
06179         anim_no_repeat _ 0 .
06180         w sweepSoundForTime: 100 withMin: 60 withMax: 70 .
06181   
06182         timeout _ cur_ts + .2 .
06183         self setGraphics: 'GR/EnergyGun/Fire' .
06184         ammo _ ammo - 1 max: 0 .
06185         inventory_item setCount: ammo .
06186       
06187         player fireProjectile: CEnergyBall withSpeed: 25 .
06188       ] .
06189     ] .
06190   
06191     ammo = 0 ifTrue: [
06192       player removeItem: inventory_item .
06193     ] .
06194 
06195                                   CONSTRUCTOR
06196   
06197   init | |
06198     count _ 12  .
06199     #world addThing: self .
06200     item_class _ CEnergyGun .
06201     template _ #world getThingTemplate: 'CEnergyGunPickup' .
06202     ^ self
06203 
06204                                   CONSTRUCTOR
06205   
06206   init | |
06207     is_ceil _ 0 .
06208     ^ self
06209   
06210 
06211                                     getTileX
06212   
06213   getTileX->CFrogNum || ^ tile_x
06214 
06215                                     getTileY
06216   
06217   getTileY ->CFrogNum || ^ tile_y
06218 
06219                                     putStain
06220   
06221   putAtX:xx=CFrogNum atY: yy=CFrogNum -> * | |
06222     x _ xx rem: 128 .
06223     y _ yy rem: 128 .
06224     tile_x _ xx / 128 .
06225     tile_y _ yy / 128 .
06226   
06227 
06228                                      ADDALL
06229   
06230   addAll: vec* ->CFrogArray | |
06231     vec do: [:v=CFrogThing | self add: v ]
06232 
06233                                     COLLECT
06234   
06235   collect: block=CFrogBlock -> CFrogArray | ret=CFrogArray |
06236     ret _ # ( ) .
06237     self do: [:v* |
06238       ret add: (block value: v ) 
06239     ] .
06240     ^ ret
06241 
06242                                   CONSTRUCTOR
06243   
06244   new -> CFrogArray | |
06245    ^ self basicNew
06246   
06247 
06248                                     COPYFROM
06249   
06250   
06251 
06252                                      DETECT
06253   
06254   detect: block=CFrogBlock ->CFrogNum  | idx=CFrogNum sz=CFrogNum |
06255     sz _ self size .
06256     idx _ 0 .
06257     [
06258      idx < sz
06259     ] whileTrue : [
06260       (block value: (self at: idx )) ifTrue: [^ idx ] .
06261       idx _ idx + 1 .
06262     ].
06263      ^ -1
06264 
06265                                        DO
06266   
06267   do: block=CFrogBlock ->* | idx=CFrogNum sz=CFrogNum copy=CFrogArray|
06268     sz _ self size .
06269     copy _ self copy .
06270     'Make a copy to avoid items disappearing in loop' .
06271     idx _ 0 .
06272     [ idx < sz ] whileTrue: [
06273       block value: (copy at: idx ) .
06274       idx _ idx + 1
06275     ] .
06276 
06277                                      FIRST
06278   
06279   first  ->* | |
06280     ^ self at: 0
06281 
06282                                     INCLUDES
06283   
06284   includes: has* ->CFrogNum | |
06285     self do: [:v*| v = has ifTrue: [ ^ 1 ] ] .
06286     ^ 0 
06287 
06288                                     INDEXOF
06289   
06290   indexOf: v* ->CFrogNum | idx=CFrogNum sz=CFrogNum |
06291     idx _ 0 .
06292     sz _ self size .
06293   'io ' show .
06294    sz show .
06295     [
06296       idx _ idx + 1 .
06297       idx - 1 < sz
06298     ] whileTrue: [
06299   (self at: idx - 1 ) show .
06300     v show .
06301       (self at: idx - 1 ) = v ifTrue: [^ idx - 1 ] .
06302     ].
06303     ^ -1 
06304     
06305 
06306                                     ISEMPTY
06307   
06308   isEmpty ->CFrogNum | |
06309     ^ self size = 0
06310 
06311                                       LAST
06312   
06313   last ->* | |
06314     ^ self at: (self size - 1 )
06315 
06316                                   OCCURANCESOF
06317   
06318   occurancesOf: v* ->CFrogNum | cnt=CFrogNum|
06319     cnt _ 0 .
06320     self do: [:item* |
06321       item = v ifTrue: [ cnt _ cnt + 1 ] 
06322     ] .
06323     ^ cnt
06324 
06325                                   PRINTSTRING
06326   
06327   printString->CFrogStr | ret=CFrogString |
06328     ret _ '#(' .
06329     self do:[:v* |
06330       ret _ ret , v printString .
06331       ret _ ret ,  ' ' .
06332     ] .
06333     ret _ ret ,  ')' .
06334     ^ ret
06335 
06336                                      REJECT
06337   
06338   reject:block=CFrogBlock -> CFrogArray | ret=CFrogArray|
06339     ret _ #() .
06340     self do: [:v* |
06341       (block value : v) ifFalse: [
06342         ret add: v
06343       ].
06344     ] .
06345     ^ ret
06346 
06347                                    REMOVEALL
06348   
06349   removeAll: vec=CFrogArray ->* | |
06350     vec do: [:v*|
06351       self remove: v
06352     ]
06353 
06354                                      SELECT
06355   
06356   select:block=CFrogBlock ->CFrogArray | ret=CFrogArray |
06357     ret _ #() .
06358     self do: [:v* |
06359       (block value : v) ifTrue: [
06360         ret add: v
06361       ].
06362     ] .
06363     ^ ret
06364 
06365                                       has
06366   
06367   has: v* ->CFrogNum |
06368   |
06369     self do:[:v2* | v = v2 ifTrue: [^ 1 ]].
06370     ^ 0 .
06371 
06372                                       sort
06373   
06374   sort: pred=CFrogBlock ->*
06375   |
06376     part=CFrogBlock
06377     qsort0=CFrogBlock
06378     pivot*
06379     i=CFrogNum
06380     A*
06381     B*
06382     stack=CFrogArray 
06383   |
06384     stack _ #() .
06385     part _ [:lo=CFrogNum :hi=CFrogNum |
06386       pivot _ self at: hi .
06387       pivot show .
06388       i _ lo .
06389       lo to: hi  do: [:j=CFrogNum |
06390         A _ self at: i .
06391         B _ self at: j .
06392         (pred value: pivot value: B) >= 0 ifTrue: [
06393           self at: i  put: B .
06394           self at: j put: A .
06395           i _ i + 1 .
06396         ] .
06397       ] .
06398       A _ self at: i .
06399       self at: i  put: pivot .
06400       self at: hi put: A .
06401       i
06402     ].
06403   
06404     qsort0 _ [:lo=CFrogNum :hi=CFrogNum|
06405   lo show .
06406   hi show .
06407       (lo < hi and: lo >= 0) ifTrue: [
06408         stack add: (part value: lo value: hi ).
06409         qsort0  value: lo value: stack last   - 1 .
06410         qsort0  value: stack last + 1 value: hi .
06411         stack removeAt: stack size - 1 .
06412       ] .
06413     ] .
06414   
06415   'size' show .
06416      self size show .
06417     qsort0 value: 0 value: self size - 1 . 
06418     ^ self 
06419 
06420                                   CONSTRUCTOR
06421   
06422   init | |
06423    ^ self
06424   
06425 
06426                                   CONSTRUCTOR
06427   
06428   init: name | |
06429     self open: name
06430     ^ self
06431   
06432 
06433                                   CONSTRUCTOR
06434   
06435   new | |
06436    ^ self basicNew
06437   
06438 
06439                                   CONSTRUCTOR
06440   
06441   new | |
06442    ^ self basicNew
06443   
06444 
06445                                       COPY
06446   
06447   copy ->CFrogChr | |
06448    ^ self 
06449 
06450                                   PRINTSTRING
06451   
06452   printString ->CFrogStr | ret=CFrogStr |
06453     ret _ ''.
06454     ret add: self .
06455     ^ ret
06456 
06457                                   CONSTRUCTOR
06458   
06459   
06460 
06461                                   CONSTRUCTOR
06462   
06463   init | dick |
06464     self setGraphics: 'GR/Dick/DICK' .
06465     ammo _ 100 .
06466     x _ 0 .
06467     y _ 300 .
06468     xoff _ 0 .
06469     yoff _ 0 .
06470     timeout _ 0 .
06471     inventory_item _ CUIGridItem new .
06472     inventory_item setGraphics: 'GR/Dick/DICK' .
06473     inventory_item setCount: ammo .
06474     inventory_item setItem: self .
06475     inventory_item ->name _
06476   'Frog Dick
06477   What do you think it does
06478   ' .
06479     dick _ self .
06480     inventory_item onLeftUp: [:x=CFrogNum :y=CFrogNum |
06481       #world getPlayer selectItem: dick 
06482     ].
06483     #world getPlayer addInventoryItem: inventory_item.
06484     ^ self
06485   
06486 
06487                                     animate
06488   
06489   animate ->* | p |
06490    ^ 
06491   
06492 
06493                                       fire
06494   
06495   fire ->* |
06496     player=CPlayer
06497     piss=CPissLink
06498     a=CFrogNum
06499     a2=CFrogNum
06500     force=CFrogNum
06501     piss_stream=CPissStream
06502     cur_ts=CFrogNum
06503     step=CFrogNum
06504     rand=CFrogRandom
06505     total*
06506     launch_angle=CFrogNum
06507    |
06508     player _ #world getPlayer .
06509     cur_ts _ CFrogTime now asSeconds .
06510     step _ 1 .
06511     ammo ifTrue: [
06512       timeout < cur_ts ifTrue: [
06513         #world->is_client ifTrue: [
06514           #client sendPiss .
06515         ] ifFalse: [
06516           player piss .
06517         ] .
06518         timeout _ cur_ts + .1 .
06519       ] .
06520     ] .
06521   
06522 
06523                                   CONSTRUCTOR
06524   
06525   init ->CFrogDictionary | |
06526     ^ self 
06527 
06528                                       keys
06529   
06530   keys ->CFrogArray |
06531    r=CFrogArray
06532   |
06533     r _ #(). 
06534     self doKeys:[:k=CFrogStr|
06535       r add: k
06536     ] .
06537     ^ r
06538 
06539                                   CONSTRUCTOR
06540   
06541   init | |
06542    ^ self
06543   
06544 
06545                                   CONSTRUCTOR
06546   
06547   
06548 
06549                                   PRINTSTRING
06550   
06551   printString | |
06552     ^ self class name , #error_msg 
06553 
06554                                   CONSTRUCTOR
06555   
06556   init | |
06557    ^ self
06558   
06559 
06560                                   afterRestore
06561   
06562   afterRestore ->*
06563   |
06564   |
06565     'name' show .
06566     name show .
06567     self setGraphics: name .
06568 
06569                                   CONSTRUCTOR
06570   
06571   init ->CFrogNPC | |
06572     #world addThing: self .
06573     speed _ 64 / 30 * 3.5 .
06574     health _ 100 .
06575     random_generator _ CFrogRandom new .
06576     template _ #world getThingTemplate: 'CFrogNPC' .
06577     animation_start_tS _ 0 .
06578     state _ 'Normal' . 
06579     #new_frog_conversation value: self .
06580   
06581     ^ self
06582   
06583 
06584                                      UPDATE
06585   
06586   update ->* |
06587     hit_wall=CFrogNum
06588     new_t=C3DThingTemplate
06589     ts=CFrogNum
06590     old_x=CFrogNum
06591     old_y=CFrogNum
06592     old_z=CFrogNum
06593   |
06594   'CFrogNPC' show .
06595     state show .
06596     target show .
06597     target->health show .
06598     health <= 0 ifTrue: [
06599       new_t _ #world getThingTemplate: 'CFrogNPC/DEAD' .
06600       new_t ~= template ifTrue: [
06601         self die .
06602         animation_start_tS _ CFrogTime now asSeconds .
06603         animation_no_repeat _ 1 .
06604         template _  new_t .
06605         tongue _ 0 .
06606       ] .
06607       ^ 1 .
06608     ] .
06609   
06610     ts _ CFrogTime now asSeconds .
06611   
06612     (tongue hasClass: CFrogTongue) ifTrue: [
06613       tongue update ifFalse: [
06614         tongue _ 0 
06615       ]
06616       ^ 1  .
06617     ]  ifFalse: [
06618       state = 'Angry' ifTrue: [
06619         'Try to eat the player' .
06620         speed _ 128 / 30 * 3.5 .
06621         (random_generator next  < ( 2 / 10 ) and: (self canSeeThing: target)) ifTrue: [
06622           tongue _ CFrogTongue new .
06623           tongue eatTarget: target fromFrog: self .
06624           'Populate with values' .
06625           animation_start_tS _ CFrogTime now asSeconds .
06626           animation_no_repeat _ 1 .
06627           template _ #world getThingTemplate: 'CFrogNPC/TONGUE' .
06628           tongue update.
06629           ^ 1 
06630         ]
06631       ].
06632     ] .
06633   
06634     state = 'Normal' ifTrue: [
06635        speed _ 128 / 30  * 2 . 
06636     ] .  
06637   
06638     state = 'Flee' ifTrue: [
06639       speed _ 64 / 30 * 5 .
06640       'Run away from target or in random direction'.
06641       (random_generator next < (1.5 / 10) ) ifTrue: [
06642          random_generator next < .5 ifTrue: [
06643            angle _ target angleBetween: self
06644          ] ifFalse: [
06645            angle _ (6.28 * random_generator next )
06646          ]
06647       ] .
06648     ] .
06649   
06650     'Walk around ' .
06651   
06652     template _ #world getThingTemplate: 'CFrogNPC' .
06653     animation_no_repeat _ 0 .
06654     old_x _ x .
06655     old_y _ y .
06656     old_z _ z .
06657   
06658     (target hasClass: C3DThing) ifFalse: [
06659       target _ self lookForTarget .
06660     ].
06661   
06662   
06663     ((target hasClass: C3DThing) and: target->health > 0) ifFalse: [
06664       'Cant see anyone worth attacking' .
06665       state _ 'Normal' .
06666       ^ 1 .
06667     ].
06668     state _ 'Angry' .
06669     self wander: speed withJumpVelocity: .6 withTarget: target .
06670   
06671     'Jump Randomly' .
06672   
06673     (random_generator next < (.9 / 10) and: self isOnGround) ifTrue: [
06674       momz _ #world gravity * 3 .
06675       just_jumped _ 1 .
06676     ].
06677     
06678     self isOnGround ifTrue: [
06679       just_jumped _ 0
06680     ]
06681   
06682 
06683                                     animate
06684   
06685   animate ->* ||
06686     (tongue hasClass: CFrogTongue) ifTrue: [
06687       tongue update ifFalse: [      
06688         tongue _ 0 
06689       ]
06690       ^ 1 
06691     ] .
06692   
06693 
06694                                      damage
06695   
06696   damage: amt=CFrogNum from: t=C3DThing ->* | |
06697     'blood' .
06698     1 to: amt / 6 + 5 do:[ 
06699       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_RED 
06700     ] .
06701    
06702   
06703     'Attack target if in good health '.
06704     target _ t .
06705     health >= 25 ifTrue: [
06706       state _ 'Angry' .
06707       state_start_tS _ CFrogTime now asSeconds .
06708       state_duration _ 100 .
06709     ] ifFalse: [
06710       state _ 'Flee' .
06711       state_start_tS _ CFrogTime now  asSeconds .
06712       state_duration _ 5 .
06713     ] .
06714   
06715     self damage: amt . 
06716   
06717   'Trigger state change' .
06718     self update .
06719 
06720                                    getChatBot
06721   
06722   getChatBot ->CEliza || ^ chat_bot
06723 
06724                                    setChatBot
06725   
06726   setChatBot:e=CEliza ->* ||
06727    chat_bot _ e 
06728 
06729                                       ABS
06730   
06731   abs->CFrogNum | |
06732     self < 0 ifTrue: [ ^ -1 * self ].
06733     ^ self
06734 
06735                                    BETWEENAND
06736   
06737   between: a=CFrogNum and: b=CFrogNum ->CFrogNum | |
06738     self < a ifTrue: [ ^ 0 ] .
06739     self > b ifTrue: [ ^ 0 ] .
06740     ^ 1 .
06741 
06742                                   CONSTRUCTOR
06743   
06744   dummyasspoodle
06745   ||
06746     ^ 0
06747   
06748 
06749                                       COPY
06750   
06751   copy ->CFrogNum | |
06752     ^ self + 0 .
06753     'TODO IMPLENT AT RUNTIME LEVEL' 
06754 
06755                                      DIVIDE
06756   
06757   
06758 
06759                                       MAX
06760   
06761   max: other=CFrogNum ->CFrogNum | |
06762     ^ self < other ifTrue: [^ other ] ifFalse: [ ^ self ] .
06763   
06764 
06765                                       MIN
06766   
06767   min: other=CFrogNum ->CFrogNum | |
06768     ^ self < other ifTrue: [ ^ self ] ifFalse: [^ other]
06769 
06770                                   PRINTSTRING
06771   
06772   printString->CFrogStr | ret=CFrogStr tmp=CFrogNum digits=CFrogStr digit=CFrogChr frac=CFrogNum |
06773     tmp _ self .
06774     frac _ self - self floor .
06775     digits _ '0123456789'.
06776     ret _ ''.
06777     [ tmp abs >= 1 ] whileTrue: [
06778       digit _ digits at: ((tmp rem: 10) abs floor ).
06779       ret _ digit printString , ret.
06780       tmp _ tmp / 10 .
06781     ] .
06782     frac >= 0.0001  ifTrue: [
06783       tmp _ frac .
06784       ret _ ret , '.' .
06785       [ tmp - tmp floor >= .0001 ] whileTrue: [
06786         digit _ digits at: ((tmp * 10 rem: 10) abs floor ).
06787         ret add: digit .
06788         tmp _ tmp * 10 .
06789       ] .
06790     ] .
06791     ^ ret
06792 
06793                                       REM1
06794   
06795   rem: other->CFrogNum | |
06796     '32.16 bit fixed point limit(used for remainder)' .
06797     self > 4294967296 ifTrue: [
06798       ^ 0 .
06799     ] .
06800     self < -4294967295 ifTrue: [
06801       ^ 0 .
06802     ] .
06803     other = 0 ifTrue: [^ CFrogDivideError new ].
06804     ^ self basicRem: other  
06805 
06806                                       REM2
06807   
06808   \ other | |
06809     ^ self rem: other
06810 
06811                                       TODO
06812   
06813   to: limit=CFrogNum do: block=CFrogBlock ->* | idx=CFrogNum |
06814     idx _ self .
06815     [idx < limit ] whileTrue: [
06816       block value: idx .
06817       idx _ idx + 1
06818     ] .
06819 
06820                                       and
06821   
06822   and: other=CFrogNum -> CFrogNum||
06823     self ifTrue: [ 
06824       other ifTrue: [
06825          ^ 1
06826       ]
06827     ] .
06828     ^ 0
06829 
06830                                       arg
06831   
06832   arg: y=CFrogNum -> CFrogNum| |
06833     self > 0 ifTrue: [
06834       ^ (y / self ) arctan
06835     ] .
06836     self < 0 ifTrue: [
06837       y >= 0 ifTrue: [
06838        ^  (y / self ) arctan + 3.14
06839       ] ifFalse: [
06840        ^  (y / self ) arctan - 3.14
06841       ]
06842     ].
06843     y > 0 ifTrue: [
06844       ^ 3.14 / 2 
06845     ] .
06846     ^ -3.14 / 2
06847 
06848                                    asInteger
06849   
06850   asInteger -> CFrogNum| tmp=CFrogNum |
06851     tmp _ self floor .
06852     tmp _ self - tmp . 
06853     tmp > .95 ifTrue: [
06854       ^ self ceil .
06855     ] .
06856     ^ self floor 
06857 
06858                                       not
06859   
06860   not-> CFrogNum ||
06861     self ifTrue: [ ^ 0 ] .
06862     ^ 1 
06863 
06864                                        or
06865   
06866   or: other=CFrogNum -> CFrogNum ||
06867     other ifTrue:[^ 1 ] .
06868     self ifTrue: [^ 1 ] .
06869     ^ 0
06870 
06871                                       sign
06872   
06873   sign -> CFrogNum | |
06874     self < 0 ifTrue: [^ -1 ].
06875     self > 0 ifTrue: [^ 1 ].
06876     ^ 0
06877 
06878                                     squared
06879   
06880   squared -> CFrogNum ||
06881     ^ self * self
06882 
06883                                   CONSTRUCTOR
06884   
06885   init | |
06886     mod _ 65521 .  
06887     mul _ 17364 .
06888     inc _ 1 .
06889     seed _ 1 .
06890     ^ self
06891   
06892 
06893                                      INIT2
06894   
06895   init: seed2=CFrogNum -> CFrogRandom | |
06896     self init .
06897     seed _ seed2 .
06898     ^ self 
06899 
06900                                       NEXT
06901   
06902   next ->CFrogNum | |
06903     seed _ ((seed * mul + inc ) rem: mod ) abs.
06904     ^ seed / mod 
06905 
06906                                   CONSTRUCTOR
06907   
06908   new ->CFrogStr | |
06909    ^ self basicNew
06910   
06911 
06912                                        DO
06913   
06914   do: bl=CFrogBlock ->* | s=CFrogNum e=CFrogNum |
06915     s _ 0 .
06916     e _ self size .
06917     [s < e ] whileTrue: [
06918       bl value: ( self at: s ) .
06919       s _ s  + 1 .
06920     ] .
06921      
06922 
06923                                       HASH
06924   
06925   hash ->CFrogNum | ret=CFrogNum |
06926     ret _ 5381 .
06927     self do: [:c=CFrogChr | 
06928        ret _ ret * 33 + c asciiValue
06929     ].
06930     ^ ret abs
06931 
06932                                   PRINTSTRING
06933   
06934   printString ->CFrogStr | |
06935     ^ self copy
06936 
06937                                    uppercase
06938   
06939   uppercase ->CFrogStr |
06940     ret=CFrogStr
06941   |
06942     ret _ ''.
06943     self do:[:c=CFrogChr|
06944       ret add: c uppercase 
06945     ] .
06946     ^ ret 
06947 
06948                                       wrap
06949   
06950   wrap:l=CFrogNum ->CFrogStr
06951   |
06952     r=CFrogStr
06953     tmp=CFrogStr
06954     splits=CFrogArray
06955     l2=CFrogNum
06956   |
06957     splits _ #() .
06958     tmp _ ''.
06959     0 to: self size do: [:i=CFrogNum|
06960       ((self at: i) = (' ' at: 0)) not ifTrue: [
06961         tmp add: (self at:i) .
06962       ] ifFalse: [
06963         splits add: tmp .
06964         tmp _ ''.
06965       ].
06966     ].
06967     splits add: tmp .
06968     r _ ''.
06969     l2 _ 0 .
06970     0 to: splits size do:[:i=CFrogNum|
06971       tmp _ splits at: i .
06972       (l2 + tmp size) >= l ifTrue: [
06973          r _ r , '
06974   '.
06975          l2 _ tmp size + 1 .
06976       ] ifFalse: [
06977          l2 _ l2 + tmp size + 1  .
06978       ] .
06979       r _ r , tmp , ' '.
06980     ].
06981     ^ r 
06982 
06983                                   CONSTRUCTOR
06984   
06985   new | |
06986    ^ self basicNew
06987   
06988 
06989                                   CONSTRUCTOR
06990   
06991   new | |
06992    ^ self basicNew
06993   
06994 
06995                                    getHealth
06996   
06997   getHealth->CFrogNum || ^ health
06998 
06999                                   CONSTRUCTOR
07000   
07001   init | |
07002    ^ self
07003   
07004 
07005                                   CONSTRUCTOR
07006   
07007   init | |
07008    ^ self
07009   
07010 
07011                                    asSeconds
07012   
07013   asSeconds ->CFrogNum | |
07014     ^ ts 
07015 
07016                                   CONSTRUCTOR
07017   
07018   init | |
07019     speed _ 2 .
07020     hit _ #() .
07021     going_back _ 0 .
07022     color _ #color_LTRED .
07023     thick _ 6 .
07024    ^ self
07025   
07026 
07027                                    eatTarget
07028   
07029   eatTarget: thing=C3DThing  fromFrog: f=C3DThing ->* |
07030     angle=CFrogNum
07031     xx=CFrogNum
07032     yy=CFrogNum
07033     dist=CFrogNum
07034    |
07035     from _ f .
07036     xx _ thing ->x - from ->x.
07037     yy _ thing ->y - from ->y.
07038     angle _ xx arg: yy .
07039     dist _ (xx squared + yy squared ) sqrt + 32 max: 128 * 8 .
07040     target_x _ from ->x + (dist * angle cos ).
07041     target_y _ from ->y + (dist * angle sin ).
07042     target_z _ thing ->z + .5 .
07043     start_tS _ CFrogTime now asSeconds .
07044 
07045                                      update
07046   
07047   update -> CFrogNum |
07048     t=CFrogNum
07049     lerp=CFrogBlock
07050     tilex=CFrogNum
07051     tiley=CFrogNum 
07052     hit_block=CFrogNum
07053     dist=CFrogNum
07054     things=CFrogArray
07055     fx=CFrogNum
07056     fy=CFrogNum
07057     force=CFrogNum
07058     r*
07059     dist2=CFrogNum
07060     angle=CFrogNum
07061     from_tongue=CFrogNum
07062    |
07063     going_back ifTrue: [
07064       t _ ((CFrogTime now asSeconds - start_tS)   )  * speed + (3.14 / 2 ) .
07065     ] ifFalse: [
07066       t _ ((CFrogTime now asSeconds - start_tS)   )  * speed .
07067     ] .
07068     t > 3.14 ifTrue: [
07069       ^ 0 
07070     ] .
07071     lerp _ [:from=CFrogNum :to=CFrogNum |
07072       ((to - from ) * (t / 3.14 ) ) + from 
07073     ].
07074     t _ t sin  .
07075     fx _ from ->x .
07076     fy _ from ->y .
07077     angle _ target_x - fx arg: target_y - fy .
07078     dist _ ((target_x - fx) squared + (target_y - fy) squared ) sqrt * t .
07079   
07080     x _ (dist * angle cos ) + fx .
07081     y _ (dist * angle sin ) + fy .
07082   
07083     z _ lerp value: from ->z + .5  value: target_z .
07084     hit_block _ #world getTileAtX: x / 128 atY: y / 128 atZ: z .
07085     (hit_block and: going_back not) ifTrue: [
07086        start_tS _ CFrogTime now asSeconds .
07087        going_back _ 1 .
07088        target_x _ x .
07089        target_y _ y .
07090        target_z _ z .
07091        ^ 0 .
07092     ] .
07093   
07094     things _ #world thingsInDist: dist + 64 atAngle: angle fromThing: from .
07095   
07096     things do: [:t=C3DThing | 
07097       (t ~= from and: (hit has: t) not ) ifTrue: [
07098         dist2 _ ((t ->x - fx) squared + (t ->y - fy) squared ) sqrt .
07099         (dist + 64) > dist2 ifTrue: [
07100           from_tongue _ ((angle cos * dist2 - x + fx ) squared +
07101             (angle sin * dist2 - y + fy ) squared ) sqrt .
07102           from_tongue <= 64  ifTrue: [
07103             hit add: t .
07104             going_back ifFalse: [
07105             going_back _ 1 .
07106               target_x _ t->x .
07107               target_y _ t->y .
07108               target_z _ z .
07109               start_tS _ CFrogTime now asSeconds .
07110             ] .
07111             angle _ from->x -  t->x arg: from->y - t->y .
07112             r _ CFrogRandom new .
07113   'Throw the target towards the frog' .
07114             t damage: 10 + (r next * 7 ) from: from .
07115             force _ r next * 10 + dist2 / 30 .
07116             t addMomX: force * angle cos. 
07117             t addMomY: force * angle sin. 
07118             t addMomZ: .45 . 
07119             ^ 0 .
07120           ]
07121         ] .
07122       ]
07123     ].
07124   
07125     ^ 1
07126 
07127                                   CONSTRUCTOR
07128   
07129   init | |
07130    ^ self
07131   
07132 
07133                                   CONSTRUCTOR
07134   
07135   init | |
07136     self setGraphics: 'GR/GUN1/IDLE' .
07137     max_ammo _ 30 . 
07138     ammo _ 30 .
07139     x _ 0 .
07140     y _ 300 .
07141     xoff _ 0 .
07142     yoff _ 0 .
07143     timeout _ 0 .
07144     inventory_item _ CUIGridItem new .
07145     inventory_item setGraphics: 'GR/GUN1/IDLE' .
07146     inventory_item setCount: ammo .
07147     inventory_item setItem: self .
07148     inventory_item ->name _
07149   'Glizzy
07150   Go ganster mode and shoot
07151   some shit
07152   ' .
07153     inventory_item onLeftUp: [
07154       #world getPlayer selectItem: self .
07155     ] .
07156     #world getPlayer addInventoryItem: inventory_item .
07157     ^ self
07158   
07159 
07160                                     animate
07161   
07162   animate ->* | cur_ts=CFrogNum |
07163     cur_ts _ CFrogTime now asSeconds .
07164     inventory_item setCount: ammo  .
07165     timeout < cur_ts ifTrue: [
07166       anim_no_repeat _ 0 .
07167       self setGraphics: 'GR/GUN1/IDLE' 
07168     ] ifFalse: [
07169       anim_no_repeat _ 1 .
07170     ] .  
07171 
07172                                       fire
07173   
07174   fire ->* |
07175    cur_ts=CFrogNum
07176    player=CPlayer
07177    canidates=CFrogArray 
07178    wall_hole=CWallStain
07179    case*
07180    sz=CFrogNum
07181    floor_stain=CFloorStain
07182    best_thing*
07183    w=C3DWorldManager
07184    dmg=CFrogNum
07185    |
07186     w _ #world .
07187     player _ w getPlayer .
07188     ammo ifTrue: [
07189      
07190       cur_ts _ CFrogTime now asSeconds .
07191       timeout < cur_ts ifTrue: [
07192         case _ CShellCasing new .
07193         case setGraphics: 'GR/GUN1/BULLET' .
07194         case ejectAtX: x atY: y .
07195         anim_start_tS _ cur_ts .
07196         player addShellCasing: case .
07197         w sweepSoundForTime: 100 withMin: 50 withMax: 60 .
07198   
07199         sz _ w screenCoordToZ .
07200   
07201         timeout _ cur_ts + .25 .
07202         self setGraphics: 'GR/GUN1/FIRE' .
07203         ammo _ ammo - 1 max: 0 .
07204         inventory_item setCount: ammo .
07205         dmg _ 10 * CFrogRandom new next + 5 .
07206         player rangeAttackAtAngle: player->angle withDamage: dmg .
07207   
07208         CWallStain newStainAtX: w screenCoordToX atY: w screenCoordToY atZ: w screenCoordToZ
07209           withGraphicsLump: 'GR/GUN1/BULLET_HOLE' .
07210   
07211       ] .
07212     ] .
07213   
07214     ammo = 0 ifTrue: [
07215       player removeItem: inventory_item .
07216     ] .
07217   
07218 
07219                                   CONSTRUCTOR
07220   
07221   init | |
07222     count _ 10  .
07223     #world addThing: self .
07224     item_class _ CGun1 .
07225     template _ #world getThingTemplate: 'CGun1Pickup' .
07226     ^ self
07227   
07228 
07229                                   CONSTRUCTOR
07230   
07231   init ->* | |
07232    ^ self
07233   
07234 
07235                                 addToPlayerAgain
07236   
07237   addToPlayerAgain:p=CPlayer ->* |
07238     who=CUIGrid
07239   |
07240     in_quick_inventory ifTrue: [
07241       who _ p->quick_inventory
07242     ] ifFalse: [
07243       who _ p->main_inventory
07244     ] .
07245   
07246     inventory_item _ CUIGridItem new .
07247     inventory_item setCount: ammo .
07248     inventory_item setItem: self .
07249     inventory_item onLeftUp: [
07250       #world getPlayer selectItem: self .
07251     ].
07252   
07253     p->items add: self .
07254   
07255   
07256     who addItem: inventory_item atX: grid_x atY: grid_y .
07257   
07258 
07259                                      aimAt
07260   
07261   aimAtX: ax=CFrogNum atY: ay=CFrogNum ->* | |
07262     x _ ax .
07263     y _ 400 . 
07264 
07265                                    beforeSave
07266   
07267   beforeSave->* |
07268     p=CPlayer
07269     who=CUIGrid
07270     col=CFrogArray
07271   |
07272     p _ #world getPlayer .
07273     who _ p->quick_inventory.
07274     (who->sub_elems includes: inventory_item) ifTrue: [
07275       in_quick_inventory _ 1 .
07276     ] ifFalse: [
07277       who _ p->main_inventory .
07278       in_quick_inventory _ 0 .
07279     ] .
07280   
07281     0 to: who->mat size do: [:x=CFrogNum|
07282       col _ who->mat at: x .
07283       0 to: col size do: [:y=CFrogNum|
07284         (col at: y ) = inventory_item ifTrue: [
07285           is_equiped _ #hand_item = self .
07286           grid_x _ x .
07287           grid_y _ y .
07288           ^ 1 .
07289         ]
07290       ] .
07291     ] .
07292     ^ 0
07293 
07294                                     getAmmo
07295   
07296   getAmmo->CFrogNum | | ^ ammo
07297 
07298                                    getMaxAmmo
07299   
07300   getMaxAmmo -> CFrogNum || 
07301     ^ max_ammo
07302 
07303                                     setAmmoi
07304   
07305   setAmmo: v=CFrogNum ->*  | | ammo _ v 
07306 
07307                                   setGraphics
07308   
07309   setGraphics: str=CFrogStr
07310   ->*
07311   |
07312   |
07313     gr _ CFrogImg get:  str  .
07314     inventory_item setGraphics: str .
07315 
07316                                    setMaxAmmo
07317   
07318   setMaxAmmo: mx=CFrogNum ->* ||
07319     max_ammo _ mx .
07320 
07321                                   CONSTRUCTOR
07322   
07323   init | |
07324     count _ 5  .
07325     #world addThing: self .
07326     item_class _ CMarkerDrugItem .
07327     template _ #world getThingTemplate: 'CHealthPickup' .
07328     ^ self
07329   
07330 
07331                                   CONSTRUCTOR
07332   
07333   init | |
07334     self setGraphics: 'GR/Knife/HandIdle' .
07335     max_ammo _ 0 . 
07336     ammo _ 0 .
07337     x _ 0 .
07338     y _ 300 .
07339     xoff _ 0 .
07340     yoff _ 0 .
07341     timeout _ 0 .
07342     inventory_item _ CUIGridItem new .
07343     inventory_item setGraphics: 'GR/Knife/HandIdle' .
07344     inventory_item setCount: 0 .
07345     inventory_item setItem: self .
07346     inventory_item ->name _
07347   'Shank
07348   Yuno,the things you
07349   find in prision in 
07350   peoples rectums
07351   ' .
07352   
07353     inventory_item onLeftUp: [
07354       #world getPlayer selectItem: self .
07355     ].
07356     #world getPlayer addInventoryItem: inventory_item.
07357     ^ self
07358 
07359                                     animate
07360   
07361   animate ->* | cycle=CFrogNum tS=CFrogNum |
07362     tS _ CFrogTime now asSeconds .
07363     (timeout > 0 and: timeout > tS) ifTrue: [
07364       '2.5 Knifes per second' .
07365       cycle _ (timeout - tS) * 2.5 .
07366       xoff _ 50 * (cycle * 6.24) cos .
07367       yoff _ 75 * (cycle negated * 3.14) sin .
07368     ] ifFalse: [
07369       timeout _ 0 .
07370     ] .
07371   
07372 
07373                                       fire
07374   
07375   fire ->* |
07376     player=CPlayer
07377     target*
07378     tS=CFrogNum
07379   |
07380     player _ #world getPlayer .
07381     tS _ CFrogTime now asSeconds .
07382     timeout > tS ifTrue: [^ 0 ]. 
07383     #world sweepSoundForTime: 300 withMin: 50 withMax: 80 .
07384     timeout _ tS + (1 / 2.5) .
07385   
07386     player meleeAttackWithDamage: 35 .
07387 
07388                                   CONSTRUCTOR
07389   
07390   init | |
07391    ^ self
07392   
07393 
07394                               newLandscapeFromSeed
07395   
07396   
07397 
07398                                   CONSTRUCTOR
07399   
07400   init | |
07401    ^ self
07402   
07403 
07404                                   CONSTRUCTOR
07405   
07406   init->CLevelEditShell
07407   |
07408     level=CLevel
07409     p=CPlayer
07410     ask_str=CFrogBlock
07411     text_input=CUITextBar
07412     ui_roots=CFrogArray
07413     handled=CFrogNum
07414   |
07415     #ms_grabbed _ 0 .  
07416     ask_str _ [:result=CFrogBlock|
07417       text_input _ CUITextBar new .
07418       ui_roots add: text_input .
07419       #ui_root _ text_input .
07420       text_input->sz_x _ 200 .
07421       text_input->sz_y _ 10 .
07422       text_input->y _ 480 - 10 / 2 .
07423       text_input->x _ 640 - 200 / 2 .
07424       text_input focus .
07425       
07426       text_input focus .
07427       text_input setOnEscape: [
07428         ui_roots remove: #ui_root .
07429         #ui_root _ ui_roots last .
07430       ]. 
07431       text_input setOnEnter: [:v=CFrogStr|
07432         result value: v .
07433   'Value(should) regen menu'.
07434       ] .
07435     ].
07436   
07437     'Draw world in backgroubnd' .
07438     draw_it_name _ 'Draw3DWorld' .
07439   
07440   
07441     on_init _ [
07442   
07443     level _ #world->level .
07444     p _ #world getPlayer . 
07445     list _ CUIList new: #(
07446        #(
07447          'Save Level to Blob'
07448          [#world saveLevelToBlob]
07449        )
07450        #(
07451          'Load Level from Blob'
07452          [#world loadLevelFromBlob]
07453        )
07454        #(
07455          ('Set Level Name(' , level->display_name,')') 
07456          [ask_str value: [:v=CFrogStr|
07457             level->display_name _ v .
07458             'Regen menu' .
07459             on_init value 
07460          ]]
07461        )
07462        #(
07463          ('End when tag(',level->level_end_tag ,') is triggered')
07464          [ask_str value: [:v=CFrogStr|
07465             level->level_end_tag _ v asInteger .
07466             'Regen menu' .
07467             on_init value 
07468          ]]
07469        )
07470        #(
07471          'Set Spawn from current location'
07472          [
07473            level->spawn_x _ p->x .
07474            level->spawn_y _ p->y .
07475            level->spawn_z _ p->z .
07476          ]
07477        )
07478   
07479     ).
07480     background _ CUIBackground new .
07481     background->bg_color _ #color_LTGRAY .
07482     background addChild: list .
07483     list->x _ 10 .
07484     list->y _ 10 .
07485     background->sz_x _ list->sz_x + 20 .
07486     background->sz_y _ list->sz_y + 20 .
07487   
07488     background->x _ 100 .
07489     background->y _ 75 .
07490     #ui_root _ background .
07491     ui_roots _ #(background) .
07492     ]. 
07493     
07494     on_event _ [:v=CUIEvent |
07495       handled _ 0 .
07496       v->type = 'KeyDown' ifTrue: [
07497         v->m1 = 27 ifTrue: [
07498           'ESC '.
07499           ui_roots size <= 1 ifTrue: [
07500             exited _ 1 .
07501             handled _ 1 . 
07502           ] ifFalse: [
07503   'POP the ui menus until nothing left to pop' .
07504             ui_roots remove: (ui_roots at: ui_roots size - 1) .
07505             #ui_root _ ui_roots at: ui_roots size - 1 .
07506             handled _  1.  
07507           ] .
07508         ] .
07509       ] .
07510       handled ifFalse: [
07511         #ui_root sendEventToUI: v .
07512       ].
07513     ] .
07514   
07515   
07516     ^ self
07517   
07518 
07519                                   CONSTRUCTOR
07520   
07521   init | |
07522    ^ self
07523   
07524 
07525                                      update
07526   
07527   update->*
07528   |
07529     decay_rate=CFrogNum
07530     offset=CFrogNum
07531     w=C3DWorldManager
07532   |
07533     w _ #world .
07534     decay_rate _  4  .
07535     offset _ ((CFrogTime now asSeconds - start_tS) * decay_rate) floor.
07536     offset >= level ifTrue: [
07537       w->lights remove: self .
07538     ]. 
07539     display_level _ level - offset .
07540 
07541                                   CONSTRUCTOR
07542   
07543   init | |
07544     links _ #() .
07545     random_generator _ CFrogRandom new .
07546     ^ self
07547   
07548 
07549                                    ShootAtXYZ
07550   
07551   shootAtX: x=CFrogNum atY: y=CFrogNum atZ: z=CFrogNum ->*
07552   |
07553     angle=CFrogNum 
07554     wiggle=CFrogNum
07555     dist=CFrogNum
07556     link=CLightningLink
07557     last_link=CLightningLink
07558     normal=CFrogNum
07559     tx=CFrogNum
07560     ty=CFrogNum
07561     tz=CFrogNum
07562   |
07563     links _ #() .
07564     wiggle _ 64 .
07565     dist _ ((x - from->x) squared + (y - from->y) squared) sqrt .
07566     angle _ x - from->x arg: y - from->y .
07567     normal _ angle + (3.14 / 2).
07568     link _ CLightningLink new . 
07569     link->x _ from->x .
07570     link->y _ from->y .
07571     link->z _ from->z +.5 .
07572     link->thick _ 4 .
07573   'YELLOW/WHITE' .
07574     link->color _ 14 + (random_generator next * 2) floor .
07575     links add: link .
07576     last_link _ link .
07577     1 to: (dist / 16) floor do: [:seg=CFrogNum|
07578       link _ CLightningLink new . 
07579       tx _ from->x + (angle cos * seg * (dist/48)) .
07580       ty _ from->y + (angle sin * seg * (dist/48)) .
07581       tz _ ((z - (from->z + .5)) / dist * seg * (dist / 48)) + from->z + .5 . 
07582       link->x _ tx + ((random_generator next - .5) * normal cos * wiggle).
07583       link->y _ ty + ((random_generator next - .5 ) * normal sin * wiggle).
07584       link->z _ tz + (random_generator next - .5) .
07585       'YELLOW/WHITE' .
07586       link->color _ 14 + (random_generator next * 2) floor .  
07587       links add: link .
07588       last_link _ link
07589     ] .
07590     link->x _ x .
07591     link->y _ y .
07592     link->z _ z + .1 .
07593     'YELLOW/WHITE' .
07594     link->color _ 14 + (random_generator next * 2) floor .  
07595   
07596     next_remove_link_tS _ CFrogTime now asSeconds .
07597 
07598                                      update
07599   
07600   update->*
07601   |
07602     now=CFrogNum
07603   |
07604     'Just remove the first link until all links are rmeoved'. 
07605     'This simulates "Vanishing" after the bolt is shot'.
07606     now _ CFrogTime now asSeconds .
07607     next_remove_link_tS < now ifTrue: [
07608       next_remove_link_tS _ now + ( 1 / 20. ) .
07609       links size ifTrue: [
07610         links removeAt: 0 .
07611       ] .
07612     ]
07613 
07614                                   CONSTRUCTOR
07615   
07616   init | |
07617    ^ self
07618   
07619 
07620                                   CONSTRUCTOR
07621   
07622   init->* |
07623   |
07624     self setGraphics: 'GR/MarkerDrug/Idle' .
07625     max_ammo _ 150 . 
07626     ammo _ 30 .
07627     x _ 0 .
07628     y _ 300 .
07629     xoff _ 0 .
07630     yoff _ 0 .
07631     timeout _ 0 .
07632     state _ 'Idle' .
07633   
07634     inventory_item _ CUIGridItem new .
07635     inventory_item setGraphics: 'GR/MarkerDrug/Idle' .
07636     inventory_item setCount: ammo .
07637     inventory_item setItem: self .
07638     inventory_item ->name _
07639   'Marker
07640   Huff for health
07641   ' .
07642     inventory_item onLeftUp: [
07643       #world getPlayer selectItem: self .
07644     ] .
07645     #world getPlayer addInventoryItem: inventory_item .
07646   
07647     ^ self
07648 
07649                                     animate
07650   
07651   animate ->* | cur_ts=CFrogNum |
07652     cur_ts _ CFrogTime now asSeconds .
07653     inventory_item setCount: ammo  .
07654     (last_fire + .5 ) < cur_ts ifTrue: [
07655       anim_no_repeat _ 0 .
07656       state _ 'Idle' .
07657       self setGraphics: 'GR/MarkerDrug/Idle'
07658     ] .
07659 
07660                                       fire
07661   
07662   fire ->* |
07663     player=CPlayer
07664     case=CShellCasing
07665     cur_ts=CFrogNum
07666     rand=CFrogRandom
07667     heal=CFrogBlock
07668   |
07669     rand _ CFrogRandom new .
07670   
07671     player _ #world getPlayer .
07672   
07673     ammo ifTrue: [
07674       cur_ts _ CFrogTime now asSeconds .
07675       last_fire _ cur_ts .
07676       (timeout < cur_ts and: state = 'Idle') ifTrue: [
07677         state _ 'Prepare' .
07678         anim_start_tS _ cur_ts .
07679   
07680         timeout _ cur_ts + .45 .
07681         self setGraphics: 'GR/MarkerDrug/PreparePuff' .
07682         anim_no_repeat _ 1 .
07683         inventory_item setCount: ammo .
07684         ^ 0 .
07685       ] .
07686     
07687       heal _ [
07688         player->health _ player->health + ((rand next * 5) + 5 ) .
07689         ammo _ ammo - 1 max: 0 .
07690         self setGraphics: 'GR/MarkerDrug/Puff' .
07691         anim_no_repeat _ 0 .
07692         timeout _ cur_ts + .25 .
07693   
07694         case _ CShellCasing new .
07695         case setGraphics: 'GR/MarkerDrug/Smoke' .
07696         case ejectAtX: x atY: y .
07697         player addShellCasing: case .
07698   
07699         ^ 1 .
07700       ] .
07701   
07702       (timeout < cur_ts and: state = 'Prepare') ifTrue: [
07703         state _ 'Puff' .
07704         heal value .
07705       ].
07706       
07707       (timeout < cur_ts and: state = 'Puff') ifTrue: [
07708         heal value .
07709       ] .
07710     ] .
07711   
07712     ammo = 0 ifTrue: [
07713       player removeItem: inventory_item .
07714     ]
07715 
07716                                   CONSTRUCTOR
07717   
07718   init | |
07719     count _ 15  .
07720     #world addThing: self .
07721     item_class _ CMarkerDrugItem .
07722     template _ #world getThingTemplate: 'CMarkerDrugPickup' .
07723     ^ self
07724   
07725 
07726                                   CONSTRUCTOR
07727   
07728   init | |
07729    ^ self
07730   
07731 
07732                                  recvRemoteCall
07733   
07734   receiveRemoteCallFor: thing=CFrogThing ->*
07735   |
07736     buf=CFrogStr
07737     name=CFrogStr
07738     getInt=CFrogBlock
07739     digits=CFrogStr
07740     int=CFrogNum
07741     len=CFrogNum
07742     args*
07743   |
07744     digits _ '0123456789' .
07745     getInt _ [
07746       int _ 0 .
07747       [
07748         buf _ self getBytes: 1 .
07749         (digits indexOf: buf) ~= -1
07750       ] whileTrue: [
07751         int _ int * 10 + (digits indexOf: buf)
07752       ] .
07753       int
07754     ] .
07755   
07756     buf _ self getBytes: 1 .
07757     buf = 'C' ifTrue: [
07758       name _ '' .
07759       [
07760         buf _ self getBytes: 1 .
07761         buf ~= '.'
07762       ] whileTrue: [
07763         name addAll: buf .
07764       ] .
07765       len _ getInt value .
07766       buf _ self getBytes: 1 .
07767       buf = ':' ifTrue: [
07768         args _ (self getBytes: len) .
07769         name show .
07770         args show .
07771         args _ args restoreThing .
07772   
07773         thing callMethod: name withArguments: args .
07774       ] .
07775     ] . 
07776 
07777                                    remoteCall
07778   
07779   remoteCallMethod: name=CFrogStr withArguments: args=CFrogArray ->*
07780   |
07781     msg=CFrogStr
07782     recur=CFrogBlock 
07783     data=CFrogStr
07784   |
07785     msg _ 'C:' . 
07786     msg addAll: name .
07787     msg addAll: '.' .
07788     msg addAll: args saveString .
07789   
07790     data _ args saveThing.
07791     msg addAll: data size printString .
07792     msg addAll: ':' .
07793     msg addAll: data .
07794   
07795     self sendBytes: msg .
07796 
07797                                     sendLine
07798   
07799   sendLine: s=CFrogStr 
07800   |
07801     ln=CFrogStr
07802   |
07803     ln _ s copy.
07804     ln add: 10 asCharactor .
07805     self sendString: ln .
07806 
07807                                   CONSTRUCTOR
07808   
07809   init | |
07810     self setGraphics: 'GR/Numchucks/Idle' .
07811     max_ammo _ 0 . 
07812     ammo _ 0 .
07813     x _ 0 .
07814     y _ 300 .
07815     xoff _ 0 .
07816     yoff _ 0 .
07817     timeout _ 0 .
07818     inventory_item _ CUIGridItem new .
07819     inventory_item setGraphics: 'GR/Numchucks/Idle' .
07820     inventory_item setCount: 0 .
07821     inventory_item setItem: self .
07822     inventory_item ->name _
07823   'Numchucks
07824   Ninja some asswipes
07825   kung-fu style
07826   ' .
07827     inventory_item onLeftUp: [
07828       #world getPlayer selectItem: self .
07829     ].
07830     #world getPlayer addInventoryItem: inventory_item.
07831     ^ self
07832 
07833                                     animate
07834   
07835   animate ->* |
07836     tS=CFrogNum
07837     period=CFrogNum
07838   |
07839     tS _ CFrogTime now asSeconds .
07840     rate > .001 ifTrue: [
07841       'Stopped using numchucks so spin down' .
07842       tS > (timeout + (1 / 10)) ifTrue: [
07843         timeout _ -100 .
07844         rate _ rate - (1 / 4 ) max: 0 .
07845       ] .
07846       xoff _ ((tS - attack_start_tS) *  2 * 6.28) cos * (rate  / 3 + .1)  * 100 .
07847       yoff _ ((tS - attack_start_tS) * 4  * 6.28) sin * (rate / 3 + .1) * 20 .
07848     ] ifFalse: [
07849       'Done Spinning' .
07850       'Just move towards the center'.
07851       xoff _ xoff sign negated * 9 .
07852       xoff abs < 10 ifTrue: [
07853         xoff _ 0 .
07854       ] .
07855       yoff _ yoff sign negated * 3 .
07856       yoff abs < 4 ifTrue: [
07857         yoff _ 0 .
07858       ] .
07859       attack_start_tS _ -1 .
07860   
07861       self setGraphics: 'GR/Numchucks/Idle' .
07862     ].
07863 
07864                                       fire
07865   
07866   fire ->* |
07867     player=CPlayer
07868     target*
07869     tS=CFrogNum
07870     period=CFrogNum
07871   |
07872     player _ #world getPlayer .
07873     tS _ CFrogTime now asSeconds .
07874     tS > timeout ifTrue: [
07875       self setGraphics: 'GR/Numchucks/Attack1' .
07876       attack_start_tS < 0 ifTrue: [
07877         attack_start_tS _ tS .
07878         rate _ 0 .
07879       ] .
07880   
07881       rate _  rate + .5  min: 3 .
07882       period _ 1 / (2 + rate ).
07883       timeout _ period + tS .
07884   
07885       #world sweepSoundForTime: period * .5 * 1000 withMin: 50 withMax: 80 .
07886       
07887       player meleeAttackWithDamage: 7 .
07888     ] .
07889 
07890                                   CONSTRUCTOR
07891   
07892   init -> CPickup | |
07893    ^ self
07894   
07895 
07896                                   addToPlayer
07897   
07898   addToPlayer: player=CPlayer ->CFrogNum | item* have=CFrogArray new_cnt=CFrogNum added=CFrogNum |
07899     have _ player getInventoryItems .
07900     added _ 0 .
07901     have do: [:t* |
07902       item _ t getItem .
07903       (item hasClass: item_class) ifTrue: [
07904         new_cnt _ item getAmmo + count .
07905         item getMaxAmmo < (new_cnt) ifTrue: [
07906           'Fill up the old item and add remainder'.
07907   
07908           count _ count  - (item getMaxAmmo - item getAmmo ) max: 0 .
07909           item setAmmo: item getMaxAmmo .
07910   
07911           added _ 1 .
07912         ] ifFalse: [
07913           item setAmmo: (item getAmmo + count ) .
07914           count _  0 .
07915           added _ 1 .
07916         ] .
07917         'Animate(update icon)'. 
07918         item animate . 
07919       ]
07920     ] .
07921     count ifTrue: [
07922       item _ item_class new .
07923       item setAmmo: count .
07924       'Animate(update icon)'. 
07925       item animate . 
07926     ] .
07927     #world removeThing: self .
07928     ^ 1.
07929     
07930 
07931                                   CONSTRUCTOR
07932   
07933   init->* | |
07934     color _ #color_YELLOW .
07935     thick _ 4 .
07936     ^ self
07937   
07938 
07939                                     setFrom
07940   
07941   setFrom: f=C3DThing || from _ f 
07942 
07943                                     setMomX
07944   
07945   setMomX: m=CFrogNum ->* || momx _  m 
07946 
07947                                     setMomY
07948   
07949   setMomY: m=CFrogNum ->* || momy _  m 
07950 
07951                                     setMomZ
07952   
07953   setMomZ: m=CFrogNum ->* || momz _  m 
07954 
07955                                       setX
07956   
07957   setX: xx=CFrogNum ->* | | x _ xx . oldx _ xx . 
07958 
07959                                       setY
07960   
07961   setY: yy=CFrogNum ->* || y _ yy . oldy _ yy
07962 
07963                                       setZ
07964   
07965   setZ: zz=CFrogNum ->* || z _ zz . oldz _ zz
07966 
07967                                      update
07968   
07969   updateWithWeight: w=CFrogNum makeParticles: part=CFrogNum ->* |
07970     stain*
07971     around=CFrogArray 
07972     rand=CFrogRandom
07973     world=C3DWorld
07974     under=CFrogNum
07975     old_under=CFrogNum
07976   |
07977     world _ #world .
07978     rand _ CFrogRandom new .
07979     oldx _ x .
07980     oldy _ y .
07981     oldz _ z .
07982     x _ x + (momx * w ) .
07983     y _ y + (momy * w ) .
07984     z _ z + (momz * w ) .
07985     momz _ momz - (world gravity / 3 * w ).
07986   
07987   
07988     'Try to piss on things and damage them' .
07989     around _ world getThingsInRadiusFromX: x fromY: y withRadius: 48 .
07990     around do: [:t* |
07991       (t ->health > 0 and: t ~= from ) ifTrue: [
07992         (z - t ->z) abs < 25 ifTrue: [
07993           1 to: 3 do:  [
07994             world newParticleAtX: x atY: y atZ: oldz withSpread: 8 withColor: #color_YELLOW  withSplatLump: 'GR/Dick/PISS_STAIN'.
07995           ] .
07996           t damage: 5 * rand next + 4 from: from .
07997           ^ #(x y z)
07998         ] .
07999       ] .
08000     ] .
08001   
08002     'Use the old positions to ensure the entire piss stream in under the ground/wwal' .
08003     old_under _ 0 ~= (world getTileAtX: oldx / 128 atY: oldy / 128. atZ: oldz ).
08004     under _ 0 ~= (world getTileAtX: x / 128 atY: y / 128. atZ: z ).
08005   
08006     (old_under and: part) ifTrue: [
08007       1 to: 3 do:  [
08008         world newParticleAtX: oldx - momx atY: oldy -momy atZ: oldz -momz  withSpread: 8 withColor: #color_YELLOW  withSplatLump: 'GR/Dick/PISS_STAIN'.
08009       ] .
08010       CWallStain newStainAtX: oldx atY: oldy atZ: oldz round withGraphicsLump: 'GR/Dick/PISS_STAIN' withSpread: 64 .
08011       ^ #(x y z ) .
08012     ].
08013     ^ 1 .
08014 
08015                                   CONSTRUCTOR
08016   
08017   init | |
08018     links _ #() .
08019     ^ self
08020   
08021 
08022                                     addLink
08023   
08024   addLink:l=CPissLink ->*
08025   |
08026     tmp=CFrogArray
08027     last=CPissLink
08028   |
08029     'newest pisses come firstr in the stream' .
08030     l->connected_to_thing _ 1 .
08031     links do:[:p=CPissLink|
08032       p->connected_to_thing _ 0 .
08033     ] .
08034     tmp _  #( l ) .
08035     tmp addAll: links .
08036     tmp size > 10 ifTrue: [
08037      tmp removeAt: tmp size - 1 
08038     ] .
08039     l -> from _ from .
08040   
08041   
08042     links _ tmp .
08043 
08044                                     setFrom
08045   
08046   setFrom: t=C3DThing |
08047   |
08048     links do:[:p=CPissLink|
08049       p->from=t 
08050     ] .
08051     from _ t .
08052 
08053                                      update
08054   
08055   update ->* | tmp=CFrogArray |
08056     tmp _ links.
08057     links _ #() .
08058     tmp do:[:l=CPissLink |
08059   'Returns collision array if hit,so check for 1' .
08060       (l updateWithWeight: 1 makeParticles: 1) = 1 ifTrue: [
08061         self addLink: l .
08062       ] 
08063     ] .
08064   
08065 
08066                                   CONSTRUCTOR
08067   
08068   init ->CPlayer | |
08069     poopidex _ CPoopidex new .
08070     seen_notifications _ #() .
08071     #world addThing: self .
08072     #world getPlayer = self ifTrue: [
08073       no_draw _ 1 .
08074     ] .
08075     items _ #() .
08076     health _ 75 .
08077     shell_casings _ #() .
08078     self makeUI .
08079     piss_stream _ CPissStream new .
08080     piss_stream ->from _ self .
08081     self selectItem: CGun1 new .
08082   
08083     CFrogDick new .
08084     CEnemyEdit new.
08085     CKnife new .
08086     CTalker  new .
08087     CMarkerDrugItem new .
08088     CUzi new .
08089   
08090     CNumchucks new .
08091   
08092     template _ #world getThingTemplate: 'CFrogNPC' .
08093   
08094     quest_flags _ #() .
08095     quest_seen_responses _ #().
08096   
08097     0 to: 16 do: [:idx=CFrogNum|
08098       CWorldEditBlock new: idx .
08099     ].
08100   
08101     notifications _ #().
08102   
08103     ^ self
08104   
08105 
08106                                 addInventoryItem
08107   
08108   addInventoryItem: item=CUIGridItem -> CFrogNum  | |
08109     (quick_inventory addItem: item) ifTrue: [
08110       items add: item->item .
08111       ^ 1 .
08112     ] .
08113     (main_inventory addItem: item) ifTrue: [
08114       items add: item->item .
08115       ^ 1 
08116     ] .
08117     ^ 0
08118 
08119                                  addShellCasing
08120   
08121   addShellCasing: shell=CShellCasing -> * ||
08122     shell_casings add: shell 
08123 
08124                                   afterRestore
08125   
08126   afterRestore->*
08127   ||
08128 
08129                                     animate
08130   
08131   animate ->* |tS=CFrogNum|
08132     health_meter setValue: health .
08133     ammo_meter setValue: #hand_item getAmmo .
08134     ammo_meter setMax: 100 .
08135     piss_stream update .
08136     tS _ CFrogTime now asSeconds .
08137     message_start_tS  + 3 < tS ifTrue: [
08138       #ui_root removeChild: message .
08139       message_start_tS _ -1 .
08140     ] ifFalse: [
08141       (message hasClass: CUILabel) ifTrue: [
08142         message->x _ (640 / 2) - (message ->label size * 8 /2 ).
08143         message->y _ (480 / 4) + ((tS *7) sin  * 40) .
08144         message->color _ 10 + (tS * 2.5 floor rem: 5) floor .
08145       ] .
08146     ] .
08147   
08148     shell_casings do: [:c=CShellCasing|
08149       c update .
08150     ] .
08151   
08152   
08153     (want_hand_item hasClass: CHandItem) ifTrue: [
08154       'Just in case we hand have a valid hand item'.
08155       (#hand_item hasClass: CHandItem) ifFalse: [
08156         #hand_item _ want_hand_item .
08157         want_hand_item _ 0 . 
08158         ^ 0
08159       ].
08160   'swapt' show.
08161   (#hand_item ->timeout - tS ) show .
08162       #hand_item ->timeout <= tS ifTrue: [
08163         #hand_item _ want_hand_item .
08164         want_hand_item _ 0 . 
08165         ^ 0
08166       ].
08167     ].
08168 
08169                                  beforeRestore
08170   
08171   beforeRestore ->* | |
08172   
08173 
08174                                     chatWith
08175   
08176   chatWith: thing* ->* |
08177     eliza=CEliza
08178     name=CFrogName
08179     add_to_chat_log=CFrogBlock
08180   |
08181     eliza _ thing ->chat_bot .
08182     ( eliza hasClass: CEliza ) ifFalse: [^ 0 ].
08183     chatting_active ifTrue: [ ^ 0 ] .
08184     chatting_active _ 1 .
08185    
08186     name _ thing getName .
08187   
08188     add_to_chat_log _  [:who=CFrogStr :msg=CFrogStr|
08189       chat_log addLine: who , ': ' , msg
08190     ] . 
08191   
08192     add_to_chat_log value: name value: eliza getHello .
08193   
08194     chat_log_input setOnEnter: [:buf=CFrogStr|
08195       add_to_chat_log value: 'Player' value: buf .
08196       add_to_chat_log value: name value: (eliza message: buf ) .
08197     ] .
08198   
08199     chat_log_input focus  .
08200   
08201     CTalkShell new run .
08202   
08203 
08204                                    damageFrom
08205   
08206   damage: d=CFrogNum from: f=C3DThing ->* |
08207     w=C3DWorldManager
08208     c=C3DWorldCleint
08209   |
08210     w _ #world .
08211     w->is_server ifTrue: [
08212       c _ w getClientForPlayer: self .
08213       c sendMessage: #(d) withType: 'PDmg'.
08214     ] .
08215     self damage: d
08216 
08217                                  displayMessage
08218   
08219   displayMessage: m=CFrogStr ->*
08220   |
08221   tS=CFrogNum
08222   label=CUILabel
08223   |
08224     tS _ CFrogTime now asSeconds .
08225     message_start_tS _ tS .
08226     label _ CUILabel new .
08227     label->label _ m copy .
08228     label->color _ #color_RED .
08229     #ui_root removeChild: message .
08230     #ui_root addChild: label . 
08231     message _ label .
08232     'Update message position' .
08233     self animate .
08234 
08235                              fireProjectileAtTarget
08236   
08237   fireProjectile: type* withSpeed: speed=CFrogNum
08238     ->*
08239   |
08240     canidates=CFrogArray
08241     hit=C3DThing
08242     best_dist=CFrogNum
08243     best=C3DThing
08244     best_angle=CFrogNum
08245     dist=CFrogNum
08246     rocket*
08247     targetz=CFrogNum
08248     angle2=CFrogNum
08249   |
08250     canidates _ #world thingsInDist: 128 * 32 atAngle: angle fromThing: self .
08251     best_angle _ 3.14 / 6 .
08252     best _ 0 .
08253     canidates do: [:t=C3DThing |
08254       ((self ~= t and: t ->health > 0. ) and: (self canSeeThing: t )) ifTrue: [
08255         angle2 _ self angleFromThing: t facingAngle: angle .
08256         angle2 < best_angle ifTrue: [
08257           best_angle _ angle2  .
08258           best _ t          
08259         ]
08260       ]
08261     ] .
08262     angle2 _ angle .
08263     targetz _ z +.5 .
08264     dist _ 10000 squared .
08265     (best hasClass: C3DThing) ifTrue: [
08266       angle2 _ best->x - x arg: best->y - y .
08267       targetz _ best->z +.5 .
08268       dist _ ((best->x - x) squared + (best->y - y) squared) sqrt .
08269     ] .
08270   
08271   
08272     rocket _ type new .
08273     rocket ->from _ self .
08274     rocket ->x _ x + (32 * angle2 cos).
08275     rocket ->y _ y + (32 * angle2 sin).
08276     rocket ->z _ z + .5  .
08277     rocket ->angle _ angle2 .
08278     rocket->momx _ speed * angle2 cos .
08279     rocket->momy _ speed * angle2 sin .
08280     rocket->momz _ (targetz  - rocket ->z ) / dist sqrt * speed .
08281   
08282     #world ->is_client ifTrue: [
08283       #client shootProjectile: type 
08284         atX: rocket->x 
08285         atY: rocket->y 
08286         atZ: rocket->z
08287         withMomX: rocket->momx
08288         withMomY: rocket->momy
08289         withMomZ: rocket->momz .
08290     ].
08291   
08292     ^ rocket .
08293 
08294                                     getAngle
08295   
08296   getAngle -> CFrogNum
08297   |
08298     w=C3DWorldManager
08299   |
08300     ^ angle 
08301 
08302                                getInventroyItems
08303   
08304   getInventoryItems ->CFrogArray | res=CFrogArray |
08305     res _ quick_inventory getChildren .
08306     res addAll: main_inventory getChildren .
08307     ^ res 
08308 
08309                                  getPissStream
08310   
08311   getPissStream ->CPissStream || ^ piss_stream
08312 
08313                                       jump
08314   
08315   jump ->* ||
08316     self isOnGround ifTrue: [
08317       momz _ .55 .
08318     ]
08319 
08320                                      makeUI
08321   
08322   makeUI ->*
08323   |
08324     w=CFrogNum
08325     h=CFrogNum
08326     label*
08327     make_save_game_menu=CFrogBlock
08328     button=CUIButton
08329     load_game=C3DWorldManager
08330     end_load_save_menu=CFrogBlock
08331   |
08332     w _ 640 .
08333     h _ 480 - 16 .
08334     #ui_root _ CUIElem new .
08335     #ui_root setX: 0 .
08336     #ui_root setWidth: w  .
08337     #ui_root  setHeight: h .
08338     #ui_root setY: 0 .
08339     label _ 'Inventory' .
08340     open_inventory_button _ CUIButton new .
08341     open_inventory_button setWidth: (label size * 8) + 8 .
08342     open_inventory_button setBackgroundColor: #color_YELLOW .
08343     open_inventory_button setHeight: 10 
08344     open_inventory_button setLabel: label .
08345     open_inventory_button setY: 10  .
08346     open_inventory_button setX : ( w / 2 ).
08347   
08348     load_game_button _ CUIButton new .
08349     label _ 'Load Game' .
08350     load_game_button setBackgroundColor: #color_YELLOW .
08351     load_game_button setHeight: 10 .
08352     load_game_button setLabel: label .
08353     load_game_button setY: 10 . 
08354     load_game_button setX : ( w / 3 ).
08355   
08356     save_game_button _ CUIButton new .
08357     label _ 'Save Game' .
08358     save_game_button setBackgroundColor: #color_YELLOW .
08359     save_game_button setHeight: 10  .
08360     save_game_button setLabel: label .
08361     save_game_button setY: 10  .
08362     save_game_button setX : ( w * (2 /3) ).
08363   
08364     main_inventory _ CUIGrid new .
08365     main_inventory setWidth: 10 withHeight: 6 .
08366     main_inventory setX: (w / 2) - ( main_inventory getWidth / 2 ) .
08367     main_inventory setY: 30 .
08368    
08369     quick_inventory _ CUIGrid new .
08370     quick_inventory setWidth: 10 withHeight: 1 .
08371     quick_inventory setX: (w / 2) - ( quick_inventory getWidth / 2 ) . 
08372     quick_inventory setY: h - 50 .
08373   
08374     health_meter _ CUIMeter new .
08375     health_meter setMax: 100 .
08376     health_meter setHeight: 100 .
08377     health_meter setWidth: 100 .
08378     health_meter setY: h - 100 .
08379     health_meter setX: 10 + 50 .
08380     health_meter setLabel: 'P Power' .
08381   
08382     ammo_meter _ CUIMeter new .
08383     ammo_meter setMax: 100 .
08384     ammo_meter setHeight: 100 .
08385     ammo_meter setWidth: 100 .
08386     ammo_meter setY: h - 100 .
08387     ammo_meter setX: w - 50 - 10 .
08388     ammo_meter setLabel: 'ammo' .
08389   
08390     chat_log_input _ CUITextBar new .
08391     chat_log_input setWidth: 300 .
08392     chat_log_input setHeight: 10 .
08393     chat_log_input setY: 20 + 256 .
08394     chat_log_input setX: 320 - (chat_log_input getWidth / 2 ) .
08395     chat_log_input setOnEnter: [:s=CFrogStr | s show  ] .
08396     
08397     chat_log _ CUIChatLog new .
08398     chat_log setWidth: 300 .
08399     chat_log setHeight: 256 .
08400     chat_log setX: 320 - (chat_log getWidth / 2 ) .
08401     chat_log setY: 10 .
08402   
08403     #ui_root addChild: open_inventory_button .
08404     #ui_root addChild: quick_inventory .
08405     #ui_root addChild: health_meter .
08406     #ui_root addChild: ammo_meter .
08407     #ui_root addChild: load_game_button .
08408     #ui_root addChild: save_game_button .
08409     #ui_root addChild: ammo_meter .
08410    
08411     main_inventory_active _ 0 .
08412   
08413     make_save_game_menu _ [:is_load_game=CFrogNum|
08414       save_load_menu _ CUIBackground new .
08415       save_load_menu->bg_color _ #color_DKGRAY .
08416       save_load_menu->sz_x _ w / 2.5 .
08417       save_load_menu->sz_y _ 300 .
08418       save_load_menu->y _ 25 .
08419       save_load_menu->x _  320 - (save_load_menu->sz_x / 2 ) .
08420       
08421       label _ CUILabel new .
08422       label->color _ #color_LTCYAN .
08423       label->y _ 4 .
08424       save_load_menu addChild: label .
08425   
08426       is_load_game ifTrue: [
08427         label setLabel: 'Load Game' .
08428       ] ifFalse: [
08429         label setLabel: 'Save the Fucking Game' .
08430       ] .
08431       label->x _ (save_load_menu->sz_x / 2 ) - (label->label size * 8 / 2).
08432   
08433       end_load_save_menu _ [
08434         load_menu_active _ 0 .
08435         load_game_button setBackgroundColor: #color_YELLOW .
08436         save_game_button setBackgroundColor: #color_YELLOW .
08437         #ui_root removeChild: save_load_menu .
08438       ] .
08439       'TODO test is available' show.
08440       0 to: 10 do: [:slot=CFrogNum |
08441         button _ CUIButton new .
08442         button->bg_color _ #color_YELLOW .
08443         button->fg_color _ #color_BLACK .
08444         button->label _ 'Slot ' , slot printString .
08445         button->sz_x _ save_load_menu->sz_x  - 32 .
08446         button->sz_y _ 10 .
08447         button->x _ 16 .
08448         button->y _ 12 + (10 * slot ) .
08449         button onLeftClick: [:s=CUIButton|
08450           end_load_save_menu value .
08451           is_load_game ifTrue: [
08452             load_game _ s->label restoreThingFromSaveFile .
08453             load_game show .
08454             (load_game hasClass: C3DWorldManager) ifTrue: [
08455               #world _ load_game .
08456             ] .
08457           ] ifFalse: [
08458             s->label show .
08459             'Prevent loading with save_load_menu set' .
08460             #world saveThingToSaveFile: s->label .
08461           ] .
08462         ].
08463         save_load_menu addChild: button .
08464       ] .
08465   
08466       #ui_root addChild: save_load_menu .
08467     ] .
08468   
08469     'Save Load menu' .
08470   
08471   
08472   
08473     load_game_button onLeftClick: [
08474       'Defactivate save button' .
08475       save_game_button setBackgroundColor: #color_YELLOW .
08476       load_menu_active _ load_menu_active not .
08477       load_menu_active ifTrue: [
08478         load_game_button setBackgroundColor: #color_RED .
08479         make_save_game_menu value: 1 .
08480       ] ifFalse: [
08481         end_load_save_menu value 
08482       ] . 
08483     ] .
08484   
08485     save_game_button onLeftClick: [
08486       'Defactivate load button' .
08487       load_game_button setBackgroundColor: #color_YELLOW .
08488       load_menu_active _ load_menu_active not .
08489       load_menu_active ifTrue: [
08490         save_game_button setBackgroundColor: #color_RED .
08491         make_save_game_menu value: 0 .
08492       ] ifFalse: [
08493         end_load_save_menu value 
08494       ] . 
08495     ] .
08496   
08497     'Open/Close big inventroy' .
08498     
08499     open_inventory_button onLeftClick: [
08500       main_inventory_active _ main_inventory_active not .
08501       main_inventory_active ifTrue: [
08502         open_inventory_button setBackgroundColor: #color_RED .
08503         #ui_root addChild: main_inventory .
08504       ] ifFalse: [
08505         open_inventory_button setBackgroundColor: #color_YELLOW .
08506         #ui_root removeChild: main_inventory .
08507       ] . 
08508     ] . 
08509   
08510     chat_log_input setOnEscape: [
08511       chatting_active _ 0 .
08512       #ui_root removeChild: chat_log  .
08513       #ui_root removeChild: chat_log_input .
08514       chat_log clear 
08515     ] .
08516   
08517   
08518 
08519                                   meleeAttack
08520   
08521   meleeAttackWithDamage: damage=CFrogNum ->*
08522   |
08523     best_target=C3DThing
08524     targets=CFrogArray
08525     best_angle=CFrogNum
08526     tmp=CFrogNum
08527     rotate_weight=CFrogNum
08528   |
08529     'Todo smooth face target' .
08530     targets _ #world getThingsInRadiusFromX: x fromY: y withRadius: 128 * 2 .
08531     best_angle _ 3.14 / 4  .
08532     targets do: [:target=C3DThing |
08533       tmp _ self angleBetween: target .
08534       ((best_angle > tmp and: self ~= target) and:
08535         target->health > 0 ) ifTrue: [
08536         best_angle _ tmp .
08537         best_target _ target .
08538         target show .
08539       ] .
08540     ] .
08541     
08542     (best_target hasClass: C3DThing) ifTrue: [
08543       rotate_weight _ 1 / 3 .
08544        'Weighted averegate' .
08545        angle _ best_target->x - x arg: best_target->y - y . 
08546        #world ->is_client ifTrue: [
08547          #client sendAttackOfThing: best_target withDamage: damage .
08548        ] ifFalse: [
08549          best_target damage: damage from: self
08550        ] .
08551     ].
08552   
08553   
08554   
08555 
08556                                nextInventoryItem
08557   
08558   selectNextItemByOffset: offset=CFrogNum ->CHandItem
08559   |
08560     cur=CHandItem
08561     idx=CFrogNum
08562   |
08563     cur _ #hand_item .
08564     idx _ 0 .
08565     'x/y' .
08566     quick_inventory -> mat do: [:col=CFrogArray|
08567       ((col at: 0) = cur->inventory_item and: (cur hasClass: CHandItem))
08568       ifTrue: [
08569         [offset abs > 0 ] whileTrue: [
08570           offset > 0 ifTrue: [
08571             idx _ idx + 1 .
08572           ] ifFalse: [
08573             idx _ idx - 1 .
08574           ] .
08575           idx _ idx rem: 10 .
08576           idx < 0 ifTrue: [
08577             idx _ 10 + idx .
08578           ] .
08579           cur _  self selectQuickItemByNum: idx .
08580           (cur hasClass: CHandItem) ifTrue: [
08581             offset > 0 ifTrue: [
08582               offset _ offset - 1 .
08583             ] ifFalse: [
08584               offset _ offset + 1 .
08585             ] .
08586             offset = 0 ifTrue: [
08587               ^ cur .
08588             ] .
08589           ] .
08590         ]
08591       ].
08592       idx _ idx + 1 .
08593     ] .
08594     'Nothing found?' .
08595     0 to: 10 do: [:idx2=CFrogNum |
08596       cur _  self selectQuickItemByNum: idx2 .
08597       (cur hasClass: CHandItem) ifTrue: [ ^ cur ] .
08598     ] .
08599     ^ 0.
08600 
08601                                   pissAtAngle
08602   
08603   piss ->* |
08604     piss=CPissLink
08605     a=CFrogNum
08606     a2=CFrogNum
08607     force=CFrogNum
08608     piss_stream=CPissStream
08609     step=CFrogNum
08610     rand=CFrogRandom
08611     total*
08612     launch_angle=CFrogNum
08613    |
08614     step _ 1 .
08615     #world sweepSoundForTime: 100 withMin: 80 withMax:95 .
08616     rand _ CFrogRandom new .
08617     piss_stream _ self getPissStream .
08618   
08619     force _ 80 . 
08620    
08621     a _ angle + (3.14 / 100 * rand next )  .
08622     piss _ CPissLink new .
08623     piss -> x _  x + (16 * a cos ) .
08624     piss -> y _  y + (16 * a sin ) .
08625     piss -> z _  z + .3 .
08626     a2 _ angle2 negated .
08627     piss -> momx _  (force * a cos * a2 cos ).
08628     piss -> momy _  (force * a sin * a2 cos ).
08629     'Its inverse(angle2)' .
08630     piss -> momz _  force * a2 sin / 128 .
08631     piss -> from _ self .
08632     piss_stream addLink: piss .
08633   
08634 
08635                           rangeAttackAtAngleWithDamage
08636   
08637   rangeAttackAtAngle: a=CFrogNum withDamage: d=CFrogNum
08638   ->*
08639   |
08640     best_thing=C3DThing
08641   |
08642   'attack' show .
08643     best_thing _ self  bestTargetAtAngle: a .
08644     (best_thing hasClass: C3DThing) ifTrue: [
08645       best_thing show .
08646       #world->is_client ifTrue: [
08647         #client sendAttackOfThing: best_thing withDamage: d . 
08648       ] ifFalse: [
08649          best_thing damage: d from: self
08650       ]
08651     ] .
08652 
08653                                     regenUI
08654   
08655   regenUI->* 
08656   |
08657     om=CUIGrid
08658     oq=CUIGrid
08659     g=CUIGrid
08660     target=CUIGrid
08661     have=CUIGridItem
08662   |
08663     om _ main_inventory.
08664     oq _ quick_inventory.
08665     self makeUI .
08666     0 to: 2 do:[:i=CFrogNum|
08667       g _ #( om oq) at: i .
08668       target _ #(main_inventory quick_inventory) at: i .
08669       0 to: g->mat size do:[:x=CFrogNum|
08670         0 to: (g->mat at: x) size do:[:y=CFrogNum|
08671           have _ (g->mat at: x) at: y .
08672          (have hasClass: CUIGridItem) ifTrue: [
08673     'xy' show .
08674     x show .
08675     y show .
08676       have show .
08677            g->active = have ifTrue: [
08678              g removeItem: have .
08679              target addItem: have atX: x atY: y .
08680              self selectItem: have->item.
08681            ] ifFalse: [
08682              g removeItem: have .
08683              target addItem: have atX: x atY: y .
08684            ].
08685          ].
08686         ] .
08687       ] .
08688     ] .
08689 
08690                                    removeItem
08691   
08692   removeItem: i* ->* ||
08693     quick_inventory removeItem: i . 
08694     main_inventory removeItem: i.
08695     i->item = #hand_item ifTrue: [
08696       #hand_item _ 0
08697     ]
08698 
08699                                removeShellCasing
08700   
08701   removeShellCasing: s=CShellCasing ->* | |
08702     shell_casings remove: s
08703   
08704 
08705                                    selectItem
08706   
08707   selectItem: h=CHandItem ->*
08708     |
08709      now=CFrogNum
08710      inv=CUIGridItem
08711      parent=CUIGrid
08712     |
08713     now _ CFrogTime now asSeconds .
08714     'If we are beginging to choose a new item'
08715     'be sure to reserve time for swap animation' .
08716     (want_hand_item hasClass: CHandItem) ifFalse: [
08717      '+.05 for swap animation' show.
08718      #hand_item->timeout _ #hand_item->timeout max: now +(5 / 30.) .
08719     ] .
08720     inv _ h->inventory_item .
08721     parent _ inv->parent .
08722     parent->active _ inv .
08723     want_hand_item _ h . 
08724 
08725                               selectQuickItemByNum
08726   
08727   selectQuickItemByNum: idx=CFrogNum ->CHandItem
08728   |
08729     mat=CFrogArray
08730     gi=CUIGridItem
08731   |
08732     (idx between: 0 and: 10) ifFalse: [^ 0 ] .
08733     gi _ (quick_inventory  ->mat at: idx) at: 0 .
08734     (gi hasClass: CUIGridItem) ifTrue: [
08735       #world getPlayer selectItem: gi->item .
08736       ^ gi->item 
08737     ] .
08738     ^ 0 .
08739 
08740                                     stopChat
08741   
08742   stopChat->*
08743   |
08744   |
08745     chatting_active ifFalse: [
08746       ^ 0.
08747     ] .
08748     chatting_active _ 0 .
08749     #ui_root->sub_elems remove: chat_log .
08750     #ui_root->sub_elems remove: chat_log_input .
08751 
08752                                    toggleMenu
08753   
08754   toggleMenu ->*
08755   |
08756   |
08757     #ms_grabbed _ #ms_grabbed not .
08758   
08759     main_inventory_active _ #ms_grabbed not .
08760   
08761     #ui_root removeChild: main_inventory .
08762   
08763     main_inventory_active ifTrue: [
08764       open_inventory_button setBackgroundColor: #color_RED .
08765       #ui_root addChild: main_inventory .
08766       ^ 1 .
08767     ] ifFalse: [
08768       open_inventory_button setBackgroundColor: #color_YELLOW .
08769       #ui_root removeChild: main_inventory .
08770       ^ 0 .
08771     ] . 
08772   
08773 
08774                                      update
08775   
08776   update ->* | rand=CFrogRandom foot_print=CFloorStain move_angle=CFrogNum |
08777     (last_x ~= x or: last_y ~= y) ifTrue: [ 
08778       rand _ CFrogRandom new .
08779       rand next < ( 1 / 5 ) ifTrue: [
08780         (last_x and: last_y) ifTrue: [
08781            move_angle _ (last_y / last_x) arctan.
08782         ] ifFalse: [
08783            last_x ifTrue: [
08784              last_x sign * (3.14 / 2) + (3.14 / 2) .
08785            ] ifFalse:  [
08786              last_y sign * (3.14 / 2) .
08787            ] .
08788         ].
08789         foot_print _ CFloorStain new .
08790         foot_print setGraphics: 'GR/FROG_FOOT' atAngle: angle .
08791         foot_print putAtX: x atY: y .
08792         #world addFloorStain: foot_print .
08793       ]. 
08794     ] .
08795     last_x _ x .
08796     last_y _ y .
08797   
08798 
08799                                   CONSTRUCTOR
08800   
08801   init ->CPooka | |
08802     #world addThing: self .
08803     health _ 100 .
08804     template _ #world getThingTemplate: 'CPooka' .
08805     ^ self
08806   
08807 
08808                                   CONSTRUCTOR
08809   
08810   init->CPoopMan | |
08811     #world addThing: self .
08812     template _ #world getThingTemplate: 'CPoopMan' .
08813     state_start_tS _ CFrogTime now asSeconds .
08814     state _ 'Normal' .
08815     random_generator _ CFrogRandom new .
08816     health _ 25 .
08817     no_fall_off_edge _ 1 .
08818     ^ self
08819 
08820                                    damageFrom
08821   
08822   damage: d=CFrogNum from: t=C3DThing ->* ||
08823     target _  t .
08824     self damage: d . 
08825   
08826     1 to: d / 6 + 5 do:[ 
08827       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_BROWN withSplatLump: 'GR/PoopRocket/Splat' .
08828     ] .
08829   
08830   
08831 
08832                                      update
08833   
08834   update->* |
08835     w=C3DWorldManager
08836     p=CPlayer
08837     old_x=CFrogNum 
08838     old_y=CFrogNum 
08839     old_z=CFrogNum 
08840     hit_wall=CFrogNum
08841     tS=CFrogNum 
08842     rocket=CPoopRocket
08843     dist=CFrogNum
08844     pickup=CShitItemPickup
08845   |
08846     tS _ CFrogTime now asSeconds.
08847     w _ #world .
08848   
08849     health <= 0 ifTrue: [
08850       state ~= 'Dead' ifTrue: [
08851         w sweepSoundForTime: 500 withMin: 50 withMax: 30 .
08852         pickup _ CShitItemPickup new .
08853         pickup -> x _ x .
08854         pickup -> y _ y .
08855         pickup -> z _ z .
08856         pickup -> template _ w getThingTemplate: 'CPoopMan/Dead' .
08857         state _ 'Dead' .
08858         self die .
08859         pickup -> animation_no_repeat _ 1 .
08860         pickup -> animation_start_tS _ tS .
08861       ]
08862     ] .
08863   
08864     state = 'Dead' ifTrue: [
08865       w removeThing: self .
08866       ^ 1
08867     ] .
08868   
08869     state = 'Normal' ifTrue: [
08870       steps_to_walk _  steps_to_walk - 1 .
08871       speed _ 70 / 10 *  3.4 .
08872       template _ w getThingTemplate: 'CPoopMan' .
08873       animation_no_repeat _ 0 .
08874       old_x _ x .
08875       old_y _ y .
08876       old_z _ z .
08877   
08878       (target hasClass: C3DThing) ifTrue: [
08879         (target->health <= 0) ifTrue: [
08880           p _ self lookForTarget .
08881           (self canSeeThing: p) ifTrue: [
08882             target _ p.
08883           ]
08884         ] .
08885       ] ifFalse: [
08886         p _ self lookForTarget .
08887         (self canSeeThing: p) ifTrue: [
08888           target _ p.
08889         ]
08890       ] .
08891   
08892       'Only walk around if target is defined'.
08893       (target hasClass:C3DThing) ifTrue: [
08894         self wander: speed withJumpVelocity: .55 withTarget: target .
08895         ((steps_to_walk <= 0 or: random_generator next < .2 ) and: (self canSeeThing: target)) ifTrue: [
08896           state _ 'Throw' .
08897           template _ w getThingTemplate: 'CPoopMan/Throw' .
08898           animation_no_repeat _ 1 .
08899           animation_start_tS _ tS.
08900           state_start_tS _  tS.
08901           state_duration _ 8 / 4 .
08902           angle _ (target->x - x) arg: (target->y - y) .
08903           threw _ 0 .
08904         ] .
08905       ] .
08906       steps_to_walk < 0 ifTrue: [
08907         steps_to_walk _ random_generator next * 10 * 3 .
08908       ] .
08909     ] .
08910   
08911     state = 'Throw' ifTrue: [
08912       ((tS - state_start_tS) > (6 / 4) and: threw not )ifTrue: [
08913         threw _ 1 .
08914         w noiseSoundForTime: 100 withMin: 30 withMax: 40 .
08915         rocket _ CPoopRocket new .
08916         rocket->from _ self . 
08917         rocket->x _ x . 
08918         rocket->y _ y . 
08919         rocket->z _ z + .5 .
08920         rocket -> angle _ (target->x - x arg: target->y - y ).
08921         angle _ rocket->angle .
08922         rocket->momx _ rocket->angle cos * 64 .
08923         rocket->momy _ rocket->angle sin * 64 .
08924         dist _ ((target->x - rocket->x) squared +(target->y - rocket->y)) sqrt .
08925         '64 is the throw force' .
08926         rocket->momz _ (target->z +.5 - rocket->z + ((random_generator next - .5 ) / 2 ) ) / dist * 64 .
08927       ] .
08928       (tS - state_start_tS) > state_duration ifTrue: [
08929         state _ 'Normal' .
08930         steps_to_walk _ random_generator next * 10 * 3 .
08931       ] .    
08932     ] .
08933    
08934 
08935                                   CONSTRUCTOR
08936   
08937   init ->CPoopRocket| |
08938     #world addThing: self .
08939     template _ #world getThingTemplate: 'CPoopRocket' .
08940     ^ self
08941 
08942                                   checkExplode
08943   
08944   checkExplode ->CFrogNum |
08945     in_radius=CFrogArray
08946   |
08947     in_radius _ #world getThingsInRadiusFromX: x fromY: y withRadius: 64 .
08948     in_radius do:[:t=C3DThing |
08949       (t->z - z) abs < 1.5 ifTrue: [
08950         t ~= from ifTrue: [
08951           t ->health > 0 ifTrue: [
08952             t damage: 10 from: from .
08953             self explode .
08954             ^ 1 .
08955           ]
08956         ]
08957       ] .
08958     ] .
08959     ^ 0 .
08960 
08961                                     explode
08962   
08963   explode ->CFrogNum
08964   |
08965     dist=CFrogNum 
08966     things=CFrogArray
08967     hit_wall=CFrogNum
08968     stain=CWallStain
08969     fstain=CFloorStain
08970     floorh=CFrogNum 
08971   |
08972     #world removeThing: self .
08973     things _ #world getThingsInRadiusFromX: x fromY: y withRadius:  128 .
08974     things do:[:t*|
08975       (t->z - z ) abs < 1.5 ifTrue: [
08976         t ~= from ifTrue: [
08977           dist _ ((t ->x - x) squared + (t ->y - y ) squared) sqrt .
08978           t damage: (128 - dist)/ 128 * 15 from: from  . 
08979         ] 
08980       ]
08981     ] .
08982     0 to: 10 do: [
08983       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 128 withColor: #color_BROWN withSplatLump: 'GR/PoopRocket/Splat'.
08984     ] .
08985     CWallStain newStainAtX: x atY: y atZ: z withGraphicsLump: 'GR/PoopRocket/Splat' .
08986     ^ 1 
08987   
08988 
08989                                   CONSTRUCTOR
08990   
08991   init ->*
08992   |
08993     bg=CUIBackground
08994     scroll=CUIScrollBars
08995   |
08996     categories _ CFrogDictionary new .
08997     self updateScreen .
08998     ^ self
08999   
09000 
09001                                     activate
09002   
09003   activate->*
09004   |
09005     shell=CPoopidexShell
09006   |
09007     shell _ CPoopidexShell new .
09008     shell run .
09009 
09010                                addEntryToCategory
09011   
09012   addEntry:p=CPoopidexEntry toCategory: c=CFrogStr
09013     ->*
09014   |
09015     n=CUINotification
09016   |
09017     ((categories at: c ) hasClass: CFrogArray) ifFalse: [
09018       categories at: c put: #() .
09019     ] .
09020   
09021     (categories at: c) add: p .
09022 
09023                                   updateScree
09024   
09025   updateScreen ->*
09026   |
09027     bg=CUIBackground
09028     scroll=CUIScrollBars
09029     label=CUILabel
09030     button=CUIButton
09031     keys=CFrogArray
09032     x=CFrogNum
09033     y=CFrogNum
09034     tree=CUITree
09035     labels=CFrogArray
09036     elems=CFrogArray
09037     icon=CUIcon
09038     tmp=CFrogStr
09039     dict=CFrogDictionary
09040     e=CPoopidexEntry
09041     subcatergory=CFrogStr
09042   |
09043     bg _ CUIBackground new .
09044     bg->sz_x _ 500 .
09045     bg->sz_y _ 400 .
09046     bg->x _ (640 - bg->sz_x) / 2 .
09047     bg->y _ (480 - bg->sz_y) / 2 .
09048     bg->bg_color _ #color_LTGREEN .
09049     scroll _ CUIScrollBars new .
09050     scroll->bg_color _ #color_LTGREEN .
09051     bg addChild: scroll .
09052     screen _ bg .
09053   
09054     keys _ #() .
09055     dict _ CFrogDictionary new .
09056     categories keys do:[:k=CFrogStr|
09057       (k indexOf: '/') = -1 ifTrue: [
09058         tmp _ k .
09059         subcatergory _ ''.
09060       ] ifFalse: [
09061         tmp _ k copyFrom: 0 to: (k indexOf: '/').
09062         subcatergory _ (k copyFrom: (k indexOf: '/') + 1 to: k size) ,'/'.
09063       ] .
09064       (keys has: tmp) ifFalse: [keys add: tmp].
09065       (categories at: k) do:[:e2=CPoopidexEntry|
09066         ((dict at: tmp) hasClass: CFrogArray) not ifTrue: [
09067           dict at: tmp put: #(#((subcatergory , e2->title)  e2)) .
09068         ] ifFalse: [
09069           (dict at: tmp) add: #(( subcatergory , e2->title ) e2) .
09070         ]
09071       ]
09072     ] .
09073   
09074     label _ CUILabel new .
09075     label setLabel: 'PoopIdex 64'.
09076     bg addChild: label .
09077     label->x _ (bg->sz_x/2) - (label->sz_x /2) .
09078     label->y _ 4 .
09079     label->color _ #color_RED .
09080   
09081     y _ 12 .
09082     x _ 4 .
09083     keys do:[:k=CFrogStr|
09084       button _ CUIButton new.
09085       button->label _ k copy .
09086       button->fg_color _ #color_LTRED .
09087       button->bg_color _ #color_YELLOW .
09088       button->sz_x _ k size * 8 + 8 .
09089       button->sz_y _ 10 .
09090       button->ms_ldown _ [:btn=CUIButton|
09091         scroll->sub_elems _ #(). 
09092         y _ 20 .
09093         labels _ #() .
09094         elems _ #() .
09095         (dict at: btn->label) do:[:pair=CFrogArray|
09096           e _ pair last .
09097           labels add: pair first .
09098           bg _ CUIBackground new .
09099           elems add: bg .
09100           bg ->sz_x _ 400 .
09101           bg->sz_y _ 70 .
09102           bg->bg_color _ #color_GREEN .
09103           (e->img hasClass: CFrogImg) ifTrue: [
09104             icon _ CUIIcon new .
09105             icon->img _ e->img .
09106             icon->sz_x _ 64 .
09107             icon->sz_y _ 64 .
09108             icon->x _ 3 .
09109             icon->y _ 3 .
09110             bg addChild: icon .
09111           ].
09112           label _CUILabel new .
09113           label->color _ #color_LTCYAN .
09114           label->animate _ [:lab=CUILabel |
09115             ((CFrogTime now asSeconds * 6 rem: 2) < 1) ifTrue: [
09116                lab->color _ #color_LTCYAN
09117             ] ifFalse: [
09118                lab->color _ #color_LTRED
09119             ].
09120           ] .
09121           label->y _ 3 .
09122           label->x _ 70 .
09123           label setLabel: e->title .
09124           bg addChild: label .
09125           label _CUILabel new .
09126           label->y _ 6 + 8 .
09127           label->x _ 70 .
09128           label->color _ #color_LTRED .
09129           label->label _ e->text wrap: ( bg->sz_x - label->x ) / 8 .
09130           bg addChild: label .
09131         ] .
09132         tree _ CUITree new.
09133         tree setBranchLabels: labels withElements: elems .
09134         scroll addChild: tree .
09135       ] .
09136       bg addChild: button .
09137       button->x _ x .
09138       button->y _ y .
09139       x _ button -> sz_x + x + 8 .
09140       x >= bg->sz_x  ifTrue: [
09141         y _ y + 10 .
09142         x _ 4 .
09143       ].
09144     ] .
09145     scroll->x _ 10 .
09146     scroll->y _ y + 10 . 
09147     scroll->sz_x _ bg->sz_x - 20 .
09148     scroll->sz_y _ bg->sz_y - scroll->y .
09149 
09150                                   CONSTRUCTOR
09151   
09152   initWithTitle: title0=CFrogStr
09153     withImg: img0=CFrogStr
09154     withText: text0=CFrogStr
09155     withCategory: cat=CFrogStr
09156     |
09157       p=CPlayer
09158       poop=CPoopidex
09159     |
09160     p _ #world getPlayer .
09161     img _ CFrogImg get: img0 .
09162     title _ title0 .
09163     text _ text0 .
09164     poop _ p -> poopidex .
09165     poop addEntry: self toCategory: cat .
09166     ^ self
09167   
09168 
09169                                   CONSTRUCTOR
09170   
09171   init ->*
09172   |
09173     handled=CFrogNum
09174     player=CPlayer
09175     poopidex=CPoopidex
09176   |
09177     'Draw world in backgroubnd' .
09178     draw_it_name _ 'Draw3DWorld' .
09179   
09180     on_init _ [
09181       #ms_grabbed _ 0 .
09182       #ui_root _ CUIElem new .
09183       #ui_root -> x _ 0 .
09184       #ui_root -> y _ 0 .
09185       #ui_root -> sz_x _ 640 .
09186       #ui_root -> sz_y _ 480 .
09187   
09188       player _ #world  getPlayer .
09189       poopidex _ player->poopidex .
09190       poopidex updateScreen .
09191       #ui_root addChild: poopidex->screen .
09192     ] .
09193   
09194     on_event _ [:v=CUIEvent |
09195       handled _ 0 .
09196       v->type = 'KeyDown' ifTrue: [
09197         v->m1 = 27 ifTrue: [
09198           'ESC '.
09199           exited _ 1 .
09200           handled _ 1 . 
09201         ] .
09202       ] .
09203       handled ifFalse: [
09204         #ui_root sendEventToUI: v .
09205       ].
09206     ] .
09207     ^ self
09208   
09209   
09210 
09211                                   CONSTRUCTOR
09212   
09213   init->CPorky | |
09214     #world addThing: self .
09215     template _ #world getThingTemplate: 'CPorky' .
09216     state_start_tS _ CFrogTime now asSeconds .
09217     state _ 'Normal' .
09218     random_generator _ CFrogRandom new .
09219     health _ 125 .
09220     ^ self
09221 
09222                                     animate
09223   
09224   animate ->* |
09225   |
09226     (tongue hasClass: CDogTongue) ifTrue: [
09227       tongue update ifFalse: [
09228         tongue _ 0 .
09229         state _ 'Normal' .
09230       ].
09231     ] .
09232 
09233                                    damageFrom
09234   
09235   damage: d=CFrogNum from: t=C3DThing ->* ||
09236     1 to: d / 6 + 5 do:[ 
09237       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_RED . 
09238     ] .
09239   
09240     target _  t .
09241     self damage: d . 
09242 
09243                                      update
09244   
09245   update ->*
09246   |
09247     tS=CFrogNum
09248     w=C3DWorldManager
09249     dist=CFrogNum
09250     p=CPlayer
09251     r=CFrogNum 
09252   |
09253     tS _ CFrogTime now asSeconds.
09254     w _ #world .
09255   
09256     health <= 0 ifTrue: [
09257       state ~= 'Dead' ifTrue: [
09258         w sweepSoundForTime: 500 withMin: 50 withMax: 30 .
09259         template _ w getThingTemplate: 'CPorky/Dead' .
09260         state _ 'Dead' .
09261         self die .
09262         animation_no_repeat _ 1 .
09263         animation_start_tS _ tS .
09264       ] .
09265       ^ 1 .
09266     ] .
09267   
09268     state = 'Normal' ifTrue: [
09269       template _ w getThingTemplate: 'CPorky' .
09270       animation_no_repeat _ 0 .
09271   
09272       (target hasClass: C3DThing) ifTrue: [
09273         (target->health <= 0) ifTrue: [
09274           p _ self lookForTarget .
09275           (self canSeeThing: p) ifTrue: [
09276             target _ p.
09277           ]
09278         ] .
09279       ] ifFalse: [
09280         p _ self lookForTarget .
09281         (self canSeeThing: p) ifTrue: [
09282           target _ p.
09283         ]
09284       ] .
09285   
09286       'Only walk around if target is defined'.
09287       (target hasClass: C3DThing) ifTrue: [
09288         dist _ ((target->x - x) squared + (target->y - y) squared ) sqrt .
09289         self wander: 16. withJumpVelocity: .60 withTarget: target .
09290         ((r < ( 2 / 10 ) and: (self canSeeThing: target)) 
09291           and: dist < (16 * 128) ) ifTrue: [
09292           licked _ 0 .
09293           state _ 'Lick' .
09294           template _ w getThingTemplate: 'CPorky/Lick' .
09295           animation_no_repeat _ 1 .
09296           animation_start_tS _ tS.
09297           state_start_tS _  tS.
09298           state_duration _  3. .
09299           angle _ (target->x - x) arg: (target->y - y) .
09300         ] .
09301       ] .
09302     ] .
09303   
09304   
09305     state = 'Lick' ifTrue: [
09306       ((tS - state_start_tS) > (3 / 4) and: licked not) ifTrue: [
09307         w noiseSoundForTime: 100 withMin: 30 withMax: 40 .
09308         dist _ ((target->x - x) squared +(target->y - y) squared ) sqrt .
09309         angle _ (target->x - x arg: target->y - y ).
09310         tongue _ CDogTongue new .
09311         tongue->from _ self .
09312         tongue->x _ x .
09313         tongue->y _ y .
09314         tongue->z _ z + .5 .
09315         tongue->start_tS _ tS .
09316         tongue->target_x _ x + (angle cos * (dist + 64)) .
09317         tongue->target_y _ y + (angle sin * (dist + 64)).
09318         tongue->target_z _ target ->z + .5 .
09319         licked _ 1 .
09320       ] .
09321       (tongue hasClass: CDogTongue) ifTrue: [
09322         tongue update ifFalse: [
09323           tongue _ 0 .
09324           state _ 'Normal' .
09325         ] .
09326       ] .
09327       (tS - state_start_tS) > state_duration ifTrue: [
09328         state _ 'Normal' .
09329         tongue _ 0 .
09330       ] .
09331     ] .
09332 
09333                                   CONSTRUCTOR
09334   
09335   init | |
09336     #world addThing: self .
09337     template _ #world getThingTemplate: 'CRocket' .
09338     from _ #world getPlayer .
09339     ^ self
09340 
09341                                   checkExplode
09342   
09343   checkExplode ->CFrogNum |
09344     in_radius=CFrogArray
09345   |
09346     in_radius _ #world getThingsInRadiusFromX: x fromY: y withRadius: 64 .
09347     in_radius do:[:t=C3DThing |
09348       (t->z - z ) abs < 1.5 ifTrue: [
09349         t ~= from ifTrue: [
09350           t ->health > 0 ifTrue: [
09351             t damage: 25 from: from .
09352             self explode .
09353             ^ 1 .
09354           ]
09355         ]
09356       ]
09357     ] .
09358     ^ 0 .
09359 
09360                                     explode
09361   
09362   explode ->CFrogNum
09363   |
09364     dist=CFrogNum 
09365     things=CFrogArray
09366   |
09367     things _ #world getThingsInRadiusFromX: x fromY: y withRadius: 2 * 128 .
09368     things do:[:t*|
09369       dist _ ((t ->x - x) squared + (t ->y - y ) squared) sqrt .
09370   'Dont damage through walls(Cant see)' .
09371       (t->z - z) abs < 2 ifTrue: [
09372         (self canSeeThing:  t) ifTrue: [
09373           t damage: (2 * 128 - dist) / ( 2 * 128 ) * 50  from: from . 
09374         ] .
09375       ]
09376     ] .
09377   'TODO explosion' .
09378     0 to: 20 do: [
09379       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 3 * 128 withColor: #color_LTGRAY
09380     ] .
09381     #world removeThing: self .
09382     #world newExplosionLightAtX: x / 128 atY: y / 128 atZ: z withLevel: 13 .
09383     ^ 1 
09384   
09385 
09386                                     setFrom
09387   
09388   setFrom:f=C3DThing ->* || from _ f  
09389 
09390                                   CONSTRUCTOR
09391   
09392   init ->CRocketLauncher | |
09393     self setGraphics: 'GR/RocketL/idle' .
09394     self setMaxAmmo: 50 .
09395     ammo _ 5 .
09396     x _ 0 .
09397     y _ 300 .
09398     xoff _ 0 .
09399     yoff _ 0 .
09400     timeout _ 0 .
09401     inventory_item _ CUIGridItem new .
09402     inventory_item setGraphics: 'GR/RocketL/idle' .
09403     inventory_item setCount: ammo .
09404     inventory_item setItem: self .
09405     inventory_item ->name _
09406   'Rocket Luancher
09407   Blow shit up 21
09408   ' .
09409   
09410     inventory_item onLeftUp: [
09411       #world getPlayer selectItem: self .
09412     ].
09413     #world getPlayer addInventoryItem: inventory_item .
09414     ^ self
09415 
09416                                     animate
09417   
09418   animate ->* | cur_ts=CFrogNum |
09419     cur_ts _ CFrogTime now asSeconds .
09420     inventory_item setCount: ammo  .
09421     timeout < cur_ts ifTrue: [
09422       anim_no_repeat _ 0 .
09423       self setGraphics: 'GR/RocketL/idle' 
09424     ] ifFalse: [
09425       anim_no_repeat _ 1 .
09426     ] 
09427 
09428                                       fire
09429   
09430   fire ->CFrogNum |
09431    cur_ts=CFrogNum
09432    player=CPlayer
09433    best=C3DThing 
09434    canidates=CFrogArray 
09435    sz=CFrogNum
09436    hit=CFrogNum
09437    dist=CFrogNum
09438    best_dist=CFrogNum 
09439    rocket=CRocket
09440    angle=CFrogNum
09441    targetz=CFrogNum
09442    |
09443     player _ #world getPlayer .
09444     ammo >= 1 ifTrue: [
09445       cur_ts _ CFrogTime now asSeconds .
09446       timeout < cur_ts ifTrue: [
09447         anim_start_tS _ cur_ts .
09448         timeout _ cur_ts + .75 .
09449         #world sweepSoundForTime: 300 withMin: 80 withMax: 50 .
09450         self setGraphics: 'GR/RocketL/fire' .
09451         ammo _ ammo - 1 max: 0 .
09452         inventory_item setCount: ammo .
09453         player fireProjectile: CRocket withSpeed: 75 .
09454         ammo = 0 ifTrue: [
09455           #hand_item _ 0 .
09456           player removeItem: inventory_item .
09457         ] .
09458       ] .
09459     ] .
09460   
09461     ^ 1 .
09462   
09463 
09464                                   CONSTRUCTOR
09465   
09466   init | |
09467     count _ 6  .
09468     #world addThing: self .
09469     item_class _ CRocketLauncher .
09470     template _ #world getThingTemplate: 'CRocketLauncherPickup' .
09471     ^ self
09472   
09473 
09474                                   CONSTRUCTOR
09475   
09476   init ->CShellCasing | |
09477    ^ self
09478   
09479 
09480                                     ejectAt
09481   
09482   ejectAtX: xx=CFrogNum atY: yy=CFrogNum ->* | rand=CFrogRandom |
09483     rand _ CFrogRandom new .
09484     x _ xx. 
09485     y _ yy. 
09486     'shell cordnates y moves down' .
09487     momx _ (rand next * 16 ) + 6 .
09488     momy _ (rand next * -128 ) - 8 .
09489   
09490     gravity _ 16 .
09491 
09492                                   setGraphics
09493   
09494   setGraphics: str=CFrogStr
09495   ->*
09496   |
09497   | 
09498    dc _ CFrogImg get:  str 
09499 
09500                                      update
09501   
09502   update ->* | |
09503     momy _ momy + gravity .
09504     x _ x + momx .
09505     y _ y + momy .
09506     y > 480 ifTrue: [
09507      #world getPlayer removeShellCasing: self 
09508     ]
09509 
09510                                   CONSTRUCTOR
09511   
09512   init ->CRocketLauncher | |
09513     self setGraphics: 'GR/ShitItem/Idle' .
09514     self setMaxAmmo: 25 .
09515     ammo _ 5 .
09516     x _ 0 .
09517     y _ 300 .
09518     xoff _ 0 .
09519     yoff _ 0 .
09520     timeout _ 0 .
09521     inventory_item _ CUIGridItem new .
09522     inventory_item setGraphics: 'GR/ShitItem/Icon' .
09523     inventory_item setCount: ammo .
09524     inventory_item setItem: self .
09525     inventory_item ->name _
09526   'Shit
09527   2 Hands 1 PEice
09528   ' .
09529   
09530     inventory_item onLeftUp: [
09531       #world getPlayer selectItem: self .
09532     ].
09533     #world getPlayer addInventoryItem: inventory_item .
09534     ^ self
09535 
09536                                     animate
09537   
09538   animate ->* | cur_ts=CFrogNum |
09539     cur_ts _ CFrogTime now asSeconds .
09540     inventory_item setCount: ammo  .
09541     timeout < cur_ts ifTrue: [
09542       anim_no_repeat _ 0 .
09543       self setGraphics: 'GR/ShitItem/Idle' 
09544     ] ifFalse: [
09545       anim_no_repeat _ 1 .
09546     ] 
09547 
09548                                       fire
09549   
09550   fire ->CFrogNum |
09551    cur_ts=CFrogNum
09552    player=CPlayer
09553    best=C3DThing 
09554    canidates=CFrogArray 
09555    sz=CFrogNum
09556    hit=CFrogNum
09557    dist=CFrogNum
09558    best_dist=CFrogNum 
09559    rocket=CRocket
09560    angle=CFrogNum
09561    targetz=CFrogNum
09562    |
09563     player _ #world getPlayer .
09564     ammo >= 1 ifTrue: [
09565       cur_ts _ CFrogTime now asSeconds .
09566       timeout < cur_ts ifTrue: [
09567         anim_start_tS _ cur_ts .
09568         timeout _ cur_ts + (.25 * 3.5) .
09569         #world sweepSoundForTime: 300 withMin: 50 withMax: 30 .
09570         self setGraphics: 'GR/ShitItem/Throw' .
09571         ammo _ ammo - 1 max: 0 .
09572         inventory_item setCount: ammo .
09573         player fireProjectile: CPoopRocket withSpeed: 50 .
09574       ] .
09575     ] .
09576     ammo = 0 ifTrue: [
09577       player removeItem: inventory_item .
09578     ] .
09579   
09580     ^ 1 .
09581   
09582 
09583                                   CONSTRUCTOR
09584   
09585   init | |
09586     count _ 5  .
09587     #world addThing: self .
09588     item_class _ CShitItem .
09589   'Use Dead CPoopMan as template'.
09590     animation_no_repeat _ 1 .
09591     animation_start_tS _ CFrogTime now asSeconds  .
09592     template _ #world getThingTemplate: 'CPoopMan' .
09593     ^ self
09594 
09595                                   CONSTRUCTOR
09596   
09597   init ->CShootgun | |
09598     self setGraphics: 'GR/Shootgun/idle' .
09599     self setMaxAmmo: 16 .
09600     ammo _ 8 .
09601     x _ 0 .
09602     y _ 300 .
09603     xoff _ 0 .
09604     yoff _ 0 .
09605     timeout _ 0 .
09606     inventory_item _ CUIGridItem new .
09607     inventory_item setGraphics: 'GR/Shootgun/idle' .
09608     inventory_item setCount: ammo .
09609     inventory_item setItem: self .
09610     inventory_item ->name _
09611   'Shotgun
09612   Shoot shit
09613   ' .
09614     inventory_item onLeftUp: [
09615       #world getPlayer selectItem: self .
09616     ].
09617     #world getPlayer addInventoryItem: inventory_item.
09618     ^ self
09619   
09620 
09621                                     animate
09622   
09623   animate ->* | cur_ts=CFrogNum |
09624     cur_ts _ CFrogTime now asSeconds .
09625     inventory_item setCount: ammo  .
09626     timeout < cur_ts ifTrue: [
09627       anim_no_repeat _ 0 .
09628       self setGraphics: 'GR/Shootgun/idle' 
09629     ] ifFalse: [
09630       anim_no_repeat _ 1 .
09631     ] 
09632 
09633                                       fire
09634   
09635   fire ->CFrogNum |
09636    cur_ts=CFrogNum
09637    player=CPlayer
09638    canidates=CFrogArray 
09639    case*
09640    sz=CFrogNum
09641    floor_stain=CFloorStain
09642    spread=CFrogNum
09643    hit=CFrogNum
09644    best_angle=CFrogNum
09645    from_angle=CFrogNum
09646    best_thing*
09647    w=C3DWorldManager
09648    dist=CFrogNum
09649    dmg=CFrogNum
09650    hx=CFrogNum
09651    hy=CFrogNum
09652    hz=CFrogNum
09653    |
09654     w _ #world .
09655     player _ w getPlayer .
09656     ammo >= 2 ifTrue: [
09657       cur_ts _ CFrogTime now asSeconds .
09658       timeout < cur_ts ifTrue: [
09659         anim_start_tS _ cur_ts .
09660         0 to: 2 do: [
09661         case _ CShellCasing new .
09662   'TODO shootgun shells' .
09663           case setGraphics: 'GR/GUN1/BULLET' .
09664           case ejectAtX: x atY: y .
09665           player addShellCasing: case .
09666         ] .
09667         timeout _ cur_ts + .75 .
09668         self setGraphics: 'GR/Shootgun/fire' .
09669         ammo _ ammo - 2 max: 0 .
09670         inventory_item setCount: ammo .
09671         canidates _ w thingsInDist: 128 * 64 atAngle: player getAngle fromThing: player .
09672         w noiseSoundForTime: 200 withMin: 20 withMax: 30 .
09673         
09674         dist _ w screenCoordToDist .
09675   
09676         0 to: 6 do: [
09677           spread _ CFrogRandom new next - .5  * (3.14 / 16 ) .
09678           dmg _ 10 * CFrogRandom new next + 5 .
09679           player rangeAttackAtAngle: player->angle + spread withDamage: dmg .
09680   
09681           CWallStain newStainAtX: w screenCoordToX atY: w screenCoordToY atZ: w screenCoordToZ
09682             withGraphicsLump: 'GR/GUN1/BULLET_HOLE' withSpread: spread sin * dist  .
09683         ]
09684       ].
09685     ] .
09686     ammo = 0 ifTrue: [
09687       player removeItem: inventory_item .
09688     ] .
09689   ^ 1 .
09690   
09691 
09692                                   CONSTRUCTOR
09693   
09694   init ->CShootgunPickup | |
09695     count _ 8  .
09696     #world addThing: self .
09697     item_class _ CShootgun .
09698     template _ #world getThingTemplate: 'CShootgunPickup' .
09699     ^ self
09700 
09701                                   CONSTRUCTOR
09702   
09703   init | |
09704     self setGraphics: 'GR/Keys/SmallKey' .
09705     max_ammo _ 0 . 
09706     ammo _ 0 .
09707     x _ 0 .
09708     y _ 300 .
09709     xoff _ 0 .
09710     yoff _ 0 .
09711     timeout _ 0 .
09712     inventory_item _ CUIGridItem new .
09713     inventory_item setGraphics: 'GR/Keys/SmallKey' .
09714     inventory_item setCount: ammo .
09715     inventory_item setItem: self .
09716     inventory_item ->name _
09717   'Small Key
09718   Small ass key
09719   ' .
09720     inventory_item onLeftUp: [
09721       #world getPlayer selectItem: self .
09722     ].
09723     #world getPlayer addInventoryItem: inventory_item.
09724     ^ self
09725   
09726 
09727                                   CONSTRUCTOR
09728   
09729   init | |
09730     count _ 1  .
09731     #world addThing: self .
09732     item_class _ CSmallKey .
09733     template _ #world getThingTemplate: 'CSmallKeyPickup' .
09734     ^ self
09735   
09736   
09737 
09738                                   CONSTRUCTOR
09739   
09740   init->CSmallPig | |
09741     #world addThing: self .
09742     template _ #world getThingTemplate: 'CSmallPig' .
09743     state_start_tS _ CFrogTime now asSeconds .
09744     state _ 'Normal' .
09745     random_generator _ CFrogRandom new .
09746     health _ 25 .
09747     no_fall_off_edge _ 1 .
09748     ^ self
09749 
09750                                     animate
09751   
09752   animate->*
09753   |
09754     in_rad=CFrogArray
09755   |
09756     state = 'Jump' ifTrue: [
09757       in_rad _ #world getThingsInRadiusFromX: x fromY: y withRadius: 1.5 * 128 .
09758       in_rad do:[:t=C3DThing|
09759         'Dont damage other pigs' .
09760         (t hasClass: CSmallPig) ifFalse: [
09761           (t ~= self and: t->health > 0) ifTrue: [
09762             state _ 'Normal' .
09763             t damage: 10 + (random_generator next * 15) from: self .
09764           ].
09765         ] .
09766       ] .
09767     ].
09768   
09769 
09770                                    damagefrom
09771   
09772   damage: d=CFrgoNum from: f=C3DThing
09773   ->*
09774   |
09775   |
09776     1 to: d / 6 + 4 do:[ 
09777       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_RED 
09778     ] .
09779   
09780     health _ health - d .
09781     target _ f .
09782     self update .
09783 
09784                                      update
09785   
09786   update->* |
09787     w=C3DWorldManager
09788     p=CPlayer
09789     hit_wall=CFrogNum
09790     rocket=CPoopRocket
09791     dist=CFrogNum
09792     tS=CFrogNum
09793     dist=CFrogNum
09794     force=CFrogNum
09795     angle2=CFrogNum
09796   
09797     in_rad=CFrogArray
09798   |
09799     tS _ CFrogTime now asSeconds.
09800     w _ #world .
09801   
09802     health <= 0 ifTrue: [
09803       state ~= 'Dead' ifTrue: [
09804         w noiseSoundForTime: 500 withMin: 30 withMax: 70 .
09805         momx2 _ 0 .
09806         momy2 _ 0 .
09807         state _ 'Dead' .
09808         template _ w getThingTemplate: 'CSmallPig/Dead' .
09809         self die .
09810         animation_no_repeat _ 1 .
09811         animation_start_tS _ tS .
09812       ] .
09813       ^ 0 . 
09814     ] .
09815   
09816     ((state = 'Jump') and: self isOnGround) ifTrue: [
09817       state _ 'Normal' .
09818     ] .
09819   
09820   
09821     state = 'Normal' ifTrue: [
09822       steps_to_walk _  steps_to_walk - 1 .
09823       speed _ 70 / 10 *  3.4 .
09824       template _ w getThingTemplate: 'CSmallPig' .
09825       animation_no_repeat _ 0 .
09826   
09827       (target hasClass: C3DThing) ifTrue: [
09828         (target->health <= 0) ifTrue: [
09829           p _ self lookForTarget .
09830           (self canSeeThing: p) ifTrue: [
09831             target _ p.
09832           ]
09833         ] .
09834       ] ifFalse: [
09835         p _ self lookForTarget .
09836         (self canSeeThing: p) ifTrue: [
09837           target _ p.
09838         ]
09839       ] .
09840   
09841       'Only walk around if target is defined'.
09842       ((target hasClass:C3DThing) and: target->health >0) ifTrue: [
09843         self wander: speed withJumpVelocity: .55 withTarget: target .
09844         dist _ ((target->x - x) squared + (target->y - y) squared ) sqrt .
09845         (10*128) >= dist  ifTrue: [
09846           ((steps_to_walk <= 0 or: random_generator next < .45 ) and: (self canSeeThing: target)) ifTrue: [
09847             state _ 'Jump' .
09848             w sweepSoundForTime: 500 withMin: 50 withMax: 70 .
09849             template _ w getThingTemplate: 'CSmallPig/Jump' .
09850             angle _ (target->x - x) arg: (target->y - y) .
09851             force _ 3 * 128 / 30  .
09852             angle2 _ dist arg: 128 * (target->z - z + .5 ).
09853             
09854             momx _ force * angle cos * angle2 cos .
09855             momy _ force * angle sin * angle2 cos .
09856             momz _ momz + (force * angle2 sin / 512) + .55 max: .55 . 
09857           ] .
09858         ].
09859       ] .
09860       steps_to_walk < 0 ifTrue: [
09861         steps_to_walk _ random_generator next * 10 * 1.3 .
09862       ] .
09863     ] .
09864    
09865 
09866                                   CONSTRUCTOR
09867   
09868   init ->*
09869   |
09870     handled=CFrogNum
09871     player=CPlayer
09872   |
09873     draw_it_name _ 'Draw3DWorld' .
09874   
09875     on_init _ [
09876       player _ #world getPlayer .
09877       (#ui_root hasClass: CUIElem ) ifFalse: [
09878         #ui_root _ CUIElem new .
09879         #ui_root->sz_x _ 640 .
09880         #ui_root->sz_y _ 480 .
09881       ] .
09882       #ui_root addChild: player->chat_log .
09883       #ui_root addChild: player->chat_log_input .
09884     ] . 
09885   
09886     on_event _ [:v=CUIEvent |
09887      player _ #world getPlayer .
09888      handled _ 0 .
09889      v->type='KeyDown' ifTrue: [
09890        'CH_ESC' .
09891        v->m1 = 27 ifTrue: [
09892          handled _ 1 .
09893          exited _ 1 .
09894        ] .
09895        'CH_SHIFT_ESC' .
09896        v->m1 = 28 ifTrue: [
09897          handled _ 1 .
09898          exited _ 1 .
09899        ] .
09900      ].
09901   
09902      handled ifFalse: [
09903        #ui_root sendEventToUI: v .
09904      ] .
09905      
09906      exited ifTrue: [
09907        player stopChat.
09908      ] .
09909     ] .
09910     ^ self 
09911 
09912                                   CONSTRUCTOR
09913   
09914   init | |
09915     self setGraphics: 'GR/Talker/Talker' .
09916     self setMaxAmmo: 0 .
09917     ammo _ 0 .
09918     x _ 0 .
09919     y _ 300 .
09920     xoff _ 0 .
09921     yoff _ 0 .
09922     timeout _ 0 .
09923     inventory_item _ CUIGridItem new .
09924     inventory_item setGraphics: 'GR/Talker/Talker' .
09925     inventory_item setCount: ammo .
09926     inventory_item setItem: self .
09927     inventory_item ->name _
09928   'Talker
09929   Try talking to random people
09930   ' .
09931     inventory_item onLeftUp: [
09932       #world getPlayer selectItem: self .
09933     ].
09934     #world getPlayer addInventoryItem: inventory_item.
09935     ^ self
09936 
09937                                       fire
09938   
09939   fire ->CFrogNum |
09940     player=CFrogPlayer 
09941     chatter=CEliza
09942     hit=C3DThing
09943   |
09944     player _ #world getPlayer .
09945     hit _ player bestTargetAtAngle: player->angle .
09946     hit show .
09947     chatter _ hit -> chat_bot .
09948     (chatter hasClass: CEliza) ifTrue: [ 
09949       hit getName show .
09950       player chatWith: hit .
09951        ^ 1
09952     ] .
09953     ^ 0 .
09954 
09955                                   CONSTRUCTOR
09956   
09957   init ->* |
09958     text_bar=CUITextBar
09959     grid=CUIGrid
09960     item=CUIGridItem
09961     group=CUIBackground
09962     button=CUIButton
09963     label=CUILabel
09964     scroll_bars=CUIScrollBars
09965     ui_roots=CFrogArray
09966     handled=CFrogNum
09967     old*
09968     y=CFrogNum
09969     templates=CFrogArray
09970     template=C3DThingTemplate
09971     edit_template=CFrogBlock
09972     tlabels=CFrogArray
09973     tbuttons=CFrogArray
09974     tree=CUITree
09975     n=CUINotification
09976   
09977     ask_num=CFrogBlock
09978     wet=CWorldEditThing
09979   
09980     popup=CUITextPopup
09981   |
09982     'Draw world in background' .
09983     draw_it_name _ 'Draw3DWorld' .
09984   
09985   
09986     ask_num _ [:title=CFrogBlock :cb=CFrogBlock |
09987       popup _ CUITextPopup new .
09988       popup->title _ title .
09989       popup->cb _ [:s=CFrogStr|
09990         cb value: s asInteger
09991       ] .
09992       popup run .
09993     ].
09994   
09995     edit_template _ [:template=C3DThingTemplate |
09996       #ui_root _ CUIBackground new .
09997       #ui_root->color _ #color_DKGRAY .
09998       #ui_root ->x _ 10 .
09999       #ui_root ->y _ 10 .
10000       #ui_root -> sz_x _ 640 .
10001       #ui_root -> sz_y _ 480 .
10002   
10003       y _ 20 .
10004   
10005       button _ CUIButton new .
10006       button -> sz_x _ 200 . 
10007       button -> sz_y _ 30 .
10008       button -> x _ 20 .
10009       button -> y _ y . 
10010       button -> bg_color _ #color_YELLOW .
10011       button -> fg_color _ #color_RED .
10012       button->label _ 'Add to inventory' .
10013       button onLeftUp: [
10014         wet _ CWorldEditThing new: template -> name.
10015         ask_num
10016           value: 'Tag number for thing(used for doors).'
10017           value: [:tagn=CFrogNum |
10018             wet->tag _ tagn.
10019             wet animate. 'Update icon' .
10020           ]
10021       ] .
10022       #ui_root addChild: button .
10023   
10024       y _ y + 50 .
10025   
10026       button _ CUIButton new .
10027       button -> sz_x _ 200 . 
10028       button -> sz_y _ 30 .
10029       button -> x _ 20 .
10030       button -> y _ y . 
10031       button -> bg_color _ #color_YELLOW .
10032       button -> fg_color _ #color_RED .
10033       button->label _ 'Set Front Graphics' .
10034       button onLeftUp: [
10035         template setFront: CFrogImg newFromEditor .
10036         template sendProperties .
10037       ] .
10038       #ui_root addChild: button .
10039   
10040       y _ y + 50 .
10041    
10042       button _ CUIButton new .
10043       button -> sz_x _ 200 . 
10044       button -> sz_y _ 30 .
10045       button -> x _ 50 .
10046       button -> y _ y . 
10047       button -> bg_color _ #color_YELLOW .
10048       button -> fg_color _ #color_RED .
10049       button->label _ 'Set Side Graphics' .
10050       button onLeftUp: [
10051         template setSide: CFrogImg newFromEditor .
10052         template sendProperties .
10053       ] .
10054       #ui_root addChild: button .
10055   
10056       y _ y + 50 .
10057   
10058       button _ CUIButton new .
10059       button -> sz_x _ 200 . 
10060       button -> sz_y _ 30 .
10061       button -> x _ 50 .
10062       button -> y _ y . 
10063       button -> bg_color _ #color_YELLOW .
10064       button -> fg_color _ #color_RED .
10065       button->label _ 'Set Back Graphics' .
10066       button onLeftUp: [
10067         template setBack: CFrogImg newFromEditor .
10068         template sendProperties .
10069       ] .
10070       #ui_root addChild: button .
10071   
10072       ui_roots add: #ui_root .
10073     ] .
10074   
10075   
10076     on_init _ [
10077       n _ CUINotification new: 'Click a Thing to Edit or Place it' .
10078       n setIcon: 'Icons/Button' . 
10079       n addToPoopidexCategory: 'Controls/ThingEdit' withDescription: 'Edit its visible sides or add to inventory'.
10080       n _ CUINotification new: 'Click the Big Green Button to make a new thing/thing-state' .
10081       n setIcon: 'Icons/Button' . 
10082   
10083       templates _ #() .
10084   
10085       #ms_grabbed _ 0 .
10086       #ui_root _ CUIElem new .
10087       ui_roots _ #(#ui_root) .'I make a stack of UIs that are POPed' .
10088       #ui_root -> x _ 0 .
10089       #ui_root -> y _ 0 .
10090       #ui_root -> sz_x _ 640 .
10091       #ui_root -> sz_y _ 480 .
10092       scroll_bars _ CUIScrollBars new .
10093       scroll_bars ->x _ 10 .
10094       scroll_bars ->y _ 10 .
10095       scroll_bars ->sz_y _ 460 .
10096       scroll_bars ->sz_x _ 620 .
10097       scroll_bars->bg_color _ #color_DKGRAY .
10098   
10099       label _ CUILabel new .
10100       label setLabel: 'Things Menu'.
10101       label->color _ #color_LTCYAN .
10102       label->x _ 50 .
10103       label->y _ 20 .
10104       scroll_bars addChild: label .
10105   
10106       y _ 40 .
10107   
10108       'Make a new thing button' .
10109       button _ CUIButton new . 
10110       button -> sz_x _ 200 . 
10111       button -> sz_y _ 30 .
10112       button -> x _ 20 .
10113       button -> y _ y .
10114       button -> fg_color _ #color_RED .
10115       button -> bg_color _ #color_LTGREEN .
10116       button->label _ 'Create A new Thing' .
10117       button onLeftUp: [:e*|
10118         n _ CUINotification new: 'Use a slash to make a sub-state of the thing' .
10119         n setIcon: 'Icons/File' . 
10120         n addToPoopidexCategory: 'Controls/ThingEdit' withDescription: 'Uses slashes to make substates of things. THis is useful for originization and for doing things like "CEnemy/Dead" or "CEnemy/Attack"'.
10121   
10122         #ui_root _ CUIBackground new .
10123         ui_roots add: #ui_root .
10124         #ui_root->color _ #color_DKGRAY .
10125         #ui_root ->x _ 100 .
10126         #ui_root ->y _ 200 .
10127         #ui_root -> sz_x _ 440 .
10128         #ui_root -> sz_y _ 80 .
10129         label _ CUILabel new .
10130         label setLabel: 'Enter the Item name' .
10131         label->color _ #color_LTCYAN .
10132         label->x _ 100 .
10133         label->y _ 20 .
10134         #ui_root addChild: label .
10135         text_bar _ CUITextBar new .
10136         #ui_root addChild: text_bar .
10137         text_bar->y _ 30 .
10138         text_bar->sz_x _ 400 .
10139         text_bar->sz_y _ 12 .
10140   
10141         text_bar->on_enter _ [:b=CFrogStr |
10142           template _ C3DThingTemplate new .
10143           template setName: b .
10144           template sendProperties .
10145           #world->thing_templates at: b put:  template .
10146   
10147   'POP the ui_root stack '. 
10148           ui_roots remove: (ui_roots at: ui_roots size - 1) .
10149           #ui_root _ ui_roots at: ui_roots size - 1 .
10150   
10151           edit_template value: template .
10152   
10153   
10154         ] .
10155       ] .
10156       scroll_bars addChild: button  .
10157   
10158       y _ y + 50 .
10159   
10160       tlabels _ #() .
10161       tbuttons _ #().
10162   
10163   
10164       #world ->thing_templates doKeys: [:name=CFrogStr|
10165         template _ #world getThingTemplate: name.
10166         button _ CUIButton new . 
10167         button -> sz_x _ 200 . 
10168         button -> sz_y _ 30 .
10169         button -> x _ 0 .
10170         button -> y _ 0 . 
10171         button -> bg_color _ #color_YELLOW .
10172         button -> fg_color _ #color_RED .
10173         button->user_data _ template .
10174         button->label _ 'Edit Thing ' .
10175         button onLeftUp: [:which=CUIButton|
10176           edit_template value: which->user_data .
10177         ].
10178         tlabels add: name .
10179         tbuttons add: button .
10180       ] .
10181       tree _ CUITree new .
10182       tree->y _ y .
10183       tree  setBranchLabels: tlabels withElements: tbuttons .
10184       scroll_bars addChild: tree .
10185       #ui_root addChild: scroll_bars .
10186     ] .
10187   
10188     on_event _ [:v=CUIEvent |
10189       handled _ 0 .
10190       v->type = 'KeyDown' ifTrue: [
10191         v->m1 = 27 ifTrue: [
10192           'ESC '.
10193           ui_roots size <= 1 ifTrue: [
10194             exited _ 1 .
10195             handled _ 1 . 
10196           ] ifFalse: [
10197             'POP the ui menus until nothing left to pop' .
10198             ui_roots remove: (ui_roots at: ui_roots size - 1) .
10199             #ui_root _ ui_roots at: ui_roots size - 1 .
10200             handled _  1.  
10201           ] .
10202         ] .
10203       ] .
10204       handled ifFalse: [
10205         #ui_root sendEventToUI: v .
10206       ].
10207     ] .
10208     ^ self
10209   
10210 
10211                                   CONSTRUCTOR
10212   
10213   init | |
10214    ^ self
10215   
10216 
10217                                     SetFront
10218   
10219   setWall: str=CFrogStr
10220   ->*
10221   |
10222   |
10223     wall_texture _ CFrogImg get: str .
10224     self updateTextures .
10225     self save . 
10226 
10227                                     setCeil
10228   
10229   setCeil: str=CFrogStr
10230   ->*
10231   |
10232   |
10233     ceil_texture _ CFrogImg get: str .
10234     self updateTextures .
10235     self save .
10236 
10237                                     setfloor
10238   
10239   setFloor: str=CFrogStr
10240   ->*
10241   |
10242   |
10243     floor_texture _ CFrogImg get: str .
10244     self updateTextures .
10245     self save .
10246 
10247                                   CONSTRUCTOR
10248   
10249   init -> CUIBackground | |
10250    bg_color _ #color_BLACK .
10251    ^ self
10252   
10253 
10254                                   CONSTRUCTOR
10255   
10256   init -> CUIButton | |
10257     fg_color _ #color_LTBLUE .
10258     bg_color _ #color_LTRED .
10259     label _ 'Button' .
10260     ^ self
10261   
10262 
10263                                      SETBG
10264   
10265   setBackgroundColor: c=CFrogNum ->* || bg_color _ c 
10266 
10267                                      SETFG
10268   
10269   setForegroundColor: c=CFrogNum ->* ||
10270     fg_color _ c.
10271 
10272                                     SETLABEL
10273   
10274   setLabel: str=CFrogStr ->* | |
10275    label _ str copy .
10276   
10277 
10278                                   CONSTRUCTOR
10279   
10280   init ->* | |
10281    ^ self
10282   
10283 
10284                                     ADDLINE
10285   
10286   addLine: str=CFrogStr -> CFrogNum | old=CFrogArray |
10287     old _ lines .
10288     old size < max_cnt ifTrue: [
10289      old add: str copy .
10290      ^ 1 
10291     ] .
10292     lines _ #() .
10293     old size - max_cnt - 1 to: old size do: [:i=CFrogNum |
10294       lines add: (old at: i) .
10295     ] .
10296     lines add: str copy 
10297     ^ 0
10298 
10299                                   CONSTRUCTOR
10300   
10301   init ->*  | |
10302     max_cnt _ 32 .
10303     fg_color _ #color_LTBLUE .
10304     bg_color _ #color_LTRED .
10305    ^ self
10306   
10307 
10308                                      clear
10309   
10310   clear ->* ||
10311     lines _ #() 
10312 
10313                                     ADDCHILD
10314   
10315   addChild: element=CUIElem ->* | |
10316     sub_elems add: element 
10317 
10318                                   CONSTRUCTOR
10319   
10320   init | |
10321     sub_elems _ #() .
10322    ^ self
10323   
10324 
10325                                    GETHEIGHT
10326   
10327   getHeight ->CFrogNum || ^ sz_y
10328 
10329                                     GETWIDTH
10330   
10331   getWidth ->CFrogNum ||
10332     ^ sz_x
10333 
10334                                       GETX
10335   
10336   getX ->CFrogNum || ^ x 
10337 
10338                                       GETY
10339   
10340   getY ->CFrogNum || ^ y
10341 
10342                                    ONKEYDOWN
10343   
10344   onKeyDown: block | |
10345     kbd_down _ block
10346 
10347                                     ONLCLICK
10348   
10349   onLeftClick: block=CFrogBlock ->* ||
10350     ms_ldown _ block .
10351 
10352                                     ONMSMOVE
10353   
10354   onMouseMove: block=CFrogBlock ->* ||
10355     ms_move _ block 
10356 
10357                                     ONRCLICK
10358   
10359   onRightClick: block=CFrogBlock ->* ||
10360     ms_rdown _ block 
10361 
10362                                     REMCHILD
10363   
10364   removeChild: element=CUIElem ->* | |
10365     sub_elems remove: element 
10366 
10367                                    SETHEIGHT
10368   
10369   setHeight: v=CFrogNum ->* ||
10370     sz_y _ v
10371 
10372                                     SETWIDTH
10373   
10374   setWidth: w=CFrogNum ->* ||
10375     sz_x _ w 
10376 
10377                                       SETX
10378   
10379   setX: v=CFrogNum ->* ||
10380     x _ v 
10381 
10382                                       SETY
10383   
10384   setY: v=CFrogNum ||
10385     y _ v 
10386 
10387                                   getChildren
10388   
10389   getChildren -> CFrogArray | |
10390     ^ sub_elems copy 
10391 
10392                                    onDragEnd
10393   
10394   onDragEnd: b=CFrogBlock ->* ||
10395     drag_end _ b 
10396 
10397                                   onDragStart
10398   
10399   onDragStart: b=CFrogBlock ->* ||
10400     drag_start _ b 
10401 
10402                                     onLeftUp
10403   
10404   onLeftUp: b=CFrogBlock  ->* || ms_lup _ b .
10405 
10406                                   CONSTRUCTOR
10407   
10408   init | |
10409    ^ self
10410   
10411 
10412                                   CONSTRUCTOR
10413   
10414   init ->* | |
10415     mat _ #() .
10416     self onDragStart: [:e* :x=CFrogNum :y=CFrogNum |
10417       self dragBeginAtX:x atY: y
10418     ].
10419     self onDragEnd: [:e* :x=CFrogNum :y=CFrogNum :i*|
10420       self dragEndAtX:x atY: y
10421     ].
10422     ^ self
10423   
10424 
10425                                     SETSIZE
10426   
10427   setWidth: w=CFrogNum withHeight: h=CFrogNum ->* | tmp=CFrogArray |
10428     mat _ #() .
10429     0 to: w do: [
10430       tmp _ #() .
10431       0 to: h do: [
10432         tmp add: 0 .
10433         
10434       ] .
10435       mat add: tmp 
10436     ] .
10437     grid_w _ w .
10438     grid_h _ h .
10439     sz_x _ 8 + ( 32 *  w ) .
10440     sz_y _ 8 + ( 32 *  h ) .
10441 
10442                                     addItem
10443   
10444   addItem: i=CUIGridItem ->CFrogNum | |
10445     0 to: grid_h do:[:cy=CFrogNum|
10446       0 to: grid_w do:[:cx=CFrogNum|
10447        (self addItem: i atX: cx atY: cy) ifTrue: [
10448          ^ 1
10449        ] .
10450       ]
10451     ] .
10452     ^ 0
10453 
10454                                    addItemAt
10455   
10456   addItem: i=CUIGridItem atX: x=CFrogNum atY: y=CFrogNum 
10457     ->CFrogNum
10458   | |
10459     (((mat at: x) at: y) hasClass: CUIGridItem) ifTrue: [
10460      ^ 0
10461     ] .
10462     i setX: (x floor * 32) .
10463     i setY: (y floor * 32) .
10464     'This will remove from the parent(possibly self)' .
10465     i setParent: self .
10466     (mat at: x) at: y put: i .
10467     self addChild: i .
10468     ^ 1
10469 
10470                                    dragBegin
10471   
10472   dragBeginAtX: x=CFrogNum atY: y=CFrogNum ->CUIGridItem | item* |
10473     x _ x / 32 . 
10474     y _ y / 32 .
10475     item _ (mat at: x )  at: y .
10476     ( item hasClass: CUIGridItem ) ifTrue: [
10477       #ui_drag_item _ item .
10478       ^ item
10479     ]
10480 
10481                                     dragEnd
10482   
10483   dragEndAtX: x=CFrogNum atY: y=CFrogNum ->*
10484   |
10485     e=CUIGridItem
10486     x2=CFrogNum
10487     y2=CFrogNum
10488     swap_with=CUIGrid
10489     have=CUIGridItem
10490     have_item=CHandItem
10491     got_item=CHandItem
10492     orig_cnt=CFrogNum
10493   |
10494     e _ #ui_drag_item .
10495     (e hasClass: CUIGridItem ) ifTrue: [
10496       x _ x / 32 .
10497       y _ y / 32 .
10498       have _ ((mat at:x )at:y ). 
10499       'Try to merge'.
10500       have_item _ have->item .
10501       got_item _ e->item .
10502       (have_item class = got_item class ) ifTrue: [
10503         have_item->ammo ifTrue: [
10504           have_item->max_ammo ifTrue: [
10505             orig_cnt _ have_item->ammo .
10506             have_item->ammo _ orig_cnt + got_item->ammo min: have_item->max_ammo .
10507             got_item->ammo _ got_item->ammo - (have_item->ammo - orig_cnt) .
10508   'Update counts on CUIGridItem' .
10509             got_item animate .
10510             have_item animate .
10511             got_item->ammo < 1 ifTrue: [
10512               e->parent removeItem: e .
10513             ] .
10514             ^ 0 .
10515           ] .
10516         ] .
10517       ] .
10518       'Try to swap our current item with target one'.
10519       (have hasClass: CUIGridItem) ifTrue: [
10520         (e->parent hasClass: CUIGrid) ifTrue: [
10521            x2 _ e getParentX .
10522            y2 _ e getParentY .
10523            swap_with _ e->parent .
10524            (x2>=0 and: y2>=0) ifTrue: [
10525               swap_with removeItem: e .
10526               swap_with addItem: ((mat at:x )at:y ) atX: x2 atY: y2 .
10527            ] .
10528         ] .
10529         'Fallback' .
10530         self addItem: e atX: x atY: y      
10531       ] ifFalse: [
10532         self addItem: e atX: x atY: y
10533       ]
10534     ] . 
10535 
10536                                    removeItem
10537   
10538   removeItem: i* -> CFrogNum | idx=CFrogNum |
10539     sub_elems remove: i .
10540     mat do: [:row=CFrogArray|
10541       idx _ row indexOf: i .
10542       idx ~= -1 ifTrue: [
10543         row at: idx put: 0 .
10544         i->parent _ 0 .
10545         ^ 1 
10546       ]
10547     ]
10548 
10549                                   CONSTRUCTOR
10550   
10551   init |
10552     item2*
10553     generic*
10554   |
10555     cnt _ 1 .
10556     sz_x _ 24 .
10557     sz_y _ 24 .
10558     ^ self
10559   
10560 
10561                                     getCount
10562   
10563   getCount ->CFrogNum || ^ cnt
10564 
10565                                     getItem
10566   
10567   getItem ->* || ^ item 
10568 
10569                                    getParentX
10570   
10571   getParentX ->CFrogNum
10572     |mat=CFrogArray|
10573     (parent hasClass: CUIGrid) ifTrue: [
10574       mat _ parent->mat .
10575       0 to: mat size do: [:x=CFrogNum|
10576          ((mat at: x) has: self) ifTrue:[
10577            ^ x .
10578          ] 
10579       ] .
10580     ].
10581     ^ -1 .
10582 
10583                                    getParentY
10584   
10585   getParentY ->CFrogNum
10586     |mat=CFrogArray|
10587     (parent hasClass: CUIGrid) ifTrue: [
10588       mat _ parent->mat .
10589       mat do: [:col=CFrogArray |
10590         0 to: col size do: [:y=CFrogNum|
10591           (col at: y) = self ifTrue: [
10592              ^ y .
10593           ] .
10594         ]. 
10595       ] .
10596     ].
10597     ^ -1 .
10598 
10599                                     setCount
10600   
10601   setCount: c=CFrogNum ->* ||
10602     cnt _ c
10603 
10604                                   setGraphics
10605   
10606   setGraphics: name=CFrogStr
10607     -> *
10608   |
10609   |
10610     graphics _ CFrogImg get: name .
10611   
10612 
10613                                     setItem
10614   
10615   setItem: i* | |
10616     item _ i
10617 
10618                                    setParent
10619   
10620   setParent: grid=CUIGrid ->* | |
10621     parent isNil ifFalse: [
10622       parent removeItem: self 
10623     ].
10624     parent _ grid .
10625 
10626                                   CONSTRUCTOR
10627   
10628   init | |
10629     sub_elems _ #() .
10630    ^ self
10631   
10632 
10633                                   setGraphics
10634   
10635   setGraphics: lump=CFrogStr ->*
10636   |
10637   |
10638     img _ CFrogImg get: lump .
10639     sz_x _ img width .
10640     sz_y _ img height .
10641 
10642                                   CONSTRUCTOR
10643   
10644   init ->* | |
10645     color _ #color_YELLOW .
10646     label _ 'label:' .
10647     ^ self
10648   
10649 
10650                                     GETLABEL
10651   
10652   getLabel ->CFrogStr ||
10653     ^ label
10654 
10655                                     SETLABEL
10656   
10657   setLabel: l=CFrogStr -> * ||
10658     label _ l copy .
10659     sz_x _ l size * 8 .
10660     ^ 0
10661 
10662                                   CONSTRUCTOR
10663   
10664   init: items=CFrogArray ->CUIList |
10665     w=CFrogNum
10666     button=CUIButton
10667     elems=CFrogArray
10668   |
10669     sub_elems _ #(). 
10670     w _ 100 .
10671     elems _ items collect: [:i*|
10672       button _ CUIButton new.
10673       button->label _ i first copy .
10674       button->sz_x _ button->label size * 8 + 20 .
10675       button->sz_y _ 20 .
10676       button->ms_ldown _ i at: 1 .
10677       button->ms_ldown  show .
10678       button->bg_color _ #color_YELLOW .
10679       self addChild: button .
10680       w _ button->sz_x max: w . 
10681       button
10682     ] .
10683     sz_x _ w + 20 .
10684     sz_y _ items size * 30 + 15 .
10685     0 to: elems size do: [:idx=CFrogNum|
10686       button _ elems at: idx .
10687       button->y _ 30 * idx + 10 .
10688       button->x _ 10 .
10689       button->sz_x _ w .
10690     ] .
10691     ^ self
10692 
10693                                   CONSTRUCTOR
10694   
10695   init ->* | |
10696     bg_color _ #color_LTGRAY .
10697     fg_color _ #color_LTGREEN .
10698     border_color _ #color_BLACK .
10699     text_color _ #color_YELLOW . 
10700     str _ 'health' .
10701     ^ self
10702   
10703 
10704                                     SETLABEL
10705   
10706   setLabel: s=CFrogStr ->*  | |
10707     str _ s
10708 
10709                                      SETMAX
10710   
10711   setMax: v=CFrogNum ->* | |
10712     max _ v 
10713 
10714                                     SETVALUE
10715   
10716   setValue: v=CFrogNum  ->* | |
10717     value _ v
10718 
10719                                   CONSTRUCTOR
10720   
10721   init: msg=CFrogStr ->* |
10722     p=CPlayer
10723   |
10724     p _ #world getPlayer .
10725     (p->seen_notifications has: msg) ifTrue: [
10726       ^ 0 .
10727     ].
10728     p->seen_notifications add: msg copy .
10729     text _ msg .
10730     bg _ CUIBackground new .
10731     bg->bg_color _ #color_LTGRAY .
10732     label _ CUILabel new .
10733     label->color _ #color_LTRED .
10734     label setLabel: msg .
10735     bg->sz_x _ msg size * 8 + 20 .
10736     bg->sz_y _ 20 + 8 .
10737     bg addChild: label . 
10738     label->x _ 10 .
10739     label->y _ 10 .
10740   
10741     sub_elems _ #( bg ) .
10742   
10743     spawn_tS _ CFrogTime now asSeconds .
10744     #ui_root2 addChild: self .
10745   
10746     sz_x _ bg->sz_x .
10747     sz_y _ bg->sz_y .
10748   
10749     y _ 480 .
10750     anim_start_y _ y .
10751     x  _ 320 - (sz_x / 2 ) .
10752     self animate .
10753   
10754     p->notifications add: self .
10755   
10756     animate _ [:e*|
10757       'FANIMATE' show .
10758       self animate .
10759     ] .
10760   
10761     'ANIMATE' show.
10762     animate show .
10763     #ui_root2 show .
10764     ^ self
10765   
10766 
10767                                  addToPoopidex
10768   
10769   addToPoopidexCategory: category=CFrogStr 
10770     withDescription: d=CFrogStr
10771   ->* |
10772     p=CPoopidexEntry
10773   |
10774     p _ CPoopidexEntry newWithTitle: text
10775         withImg: icon_name 
10776         withText: d
10777         withCategory: category .
10778     ^ p
10779 
10780                                     animate
10781   
10782   animate ->*
10783   |
10784     t=CFrogNum
10785     i=CFrogNum
10786     base_y=CFrogNum
10787     n=CUINotification
10788     nots=CFrogArray
10789   |
10790     x _ 640 - sz_x .
10791     base_y _ 250 .
10792     nots _ #ui_root2->sub_elems select: [:n*|
10793       n hasClass: CUINotification
10794     ] .
10795     i _ nots indexOf: self .
10796   
10797     0 to: i do: [:idx=CFrogNum|
10798       n _ nots at: idx .
10799       base_y _   base_y + 10 + n->sz_y .
10800     ] .
10801   
10802     t _ CFrogTime now asSeconds - spawn_tS .
10803   
10804     (t * 6 rem: 2) > 1 ifTrue: [
10805       label->color _ #color_LTRED .
10806     ] ifFalse: [
10807       label->color _ #color_LTBLUE .
10808     ] .
10809   
10810     t < 1 ifTrue: [
10811       y _ anim_start_y - (480 * t) max: base_y . 
10812     ].
10813   
10814     y show .
10815   
10816     i = 0 ifTrue: [
10817       t > 2 ifTrue: [
10818         #ui_root2 removeChild: self .
10819         nots remove: self .
10820         base_y _ 250 .
10821         nots do:[:n=CUINotification|
10822           base_y _   base_y + 10 + n->sz_y .
10823           n->anim_start_y _ base_y .
10824           n->spawn_tS _ CFrogTime now asSeconds .
10825         ] .
10826       ] .
10827     ] .
10828 
10829                                     setIcon
10830   
10831   setIcon: lump=CFrogStr ->*
10832   |
10833     icon=CUIIcon
10834   |
10835     icon_name _ lump .
10836     icon _ CUIIcon new .
10837     icon setGraphics: lump .
10838     bg addChild: icon .
10839   
10840     icon->sz_x _ 64 .
10841     icon->sz_y _ 64 .
10842   
10843     sz_x _ 20 + label->sz_x + icon->sz_x .
10844     sz_y _ 20 + icon->sz_y .
10845     icon->x _ 10 .
10846     icon->y _ 10 .
10847   
10848     label->x _ 10 + icon->sz_x .
10849     label->y _ sz_y / 2 - 4 .
10850   
10851     bg->sz_x _ sz_x . 
10852     bg->sz_y _ sz_y .
10853   
10854     x _ 320 -(sz_x/2) 
10855 
10856                                   CONSTRUCTOR
10857   
10858   init ->* | |
10859     'Handled by draw callback' .
10860     dont_draw_children _ 1 .
10861     self onLeftClick: [:e* :x2=CFrogNum :y2=CFrogNum |
10862       e onClickAtX: x2 atY: y2
10863     ] .
10864     scroll _ [:e* :amt=CFrogNum |
10865       y_scroll _ y_scroll - (amt * 6) max: 0 .
10866     ] .
10867     ^ self
10868   
10869 
10870                                     ONCLICK
10871   
10872   onClickAtX: x=CFrogNum atY: y=CFrogNum ->*
10873   |
10874     w=CFrogNum
10875     h=CFrogNum
10876   |
10877     w _ 0 .
10878     h _ 0 .
10879     sub_elems do: [:e=CUIElem |
10880       w _ w max: (e getX + e getWidth) .
10881       h _ h max: (e getY + e getHeight) .
10882     ] .
10883     (self getWidth - 8) <= x ifTrue: [
10884       y_scroll _ y / self getHeight * h.
10885       y_scroll < 0 ifTrue: [
10886         y_scroll _ 0
10887       ].
10888     ].
10889     (self getHeight - 8) <= y ifTrue: [
10890       x_scroll _ x / self getWidth * w.
10891       x_scroll < 0 ifTrue: [
10892         x_scroll _ 0
10893       ].
10894     ].
10895 
10896                                   CONSTRUCTOR
10897   
10898   init | |
10899    ^ self
10900   
10901 
10902                                   CONSTRUCTOR
10903   
10904   init ->* | |
10905     bg_color _ #color_RED .
10906     fg_color _ #color_YELLOW .
10907     border_color _ #color_LTGRAY .
10908     view_pos _ 0 .
10909     cur_pos _ 0 .
10910     buf _  '' .
10911     kbd_down _ [:elem=CUITextBar :ch* :sc*|
10912       'SC_ESC is 1' .
10913       sc = 1 ifTrue: [
10914         on_escape value .
10915       ] .
10916       'SC_CURSOR_LEFT is 75' .
10917       sc = 75 ifTrue: [
10918         cur_pos _ cur_pos - 1 .
10919         ch _  0
10920       ] . 
10921       'SC_CURSOR_RIGHT ' .
10922       sc = 77 ifTrue: [
10923         cur_pos _ cur_pos + 1 .
10924         ch _  0
10925       ] . 
10926       '28 is SC_ENTER' .
10927       sc = 28 ifTrue: [
10928         on_enter value: buf .
10929         buf _ '' .
10930         view_pos _ 0 .
10931         cur_pos _ 0 .
10932       ] ifFalse: [
10933         '14 is backsapce ' .
10934         (sc ~=14 and: ch isDisplayable ) ifTrue: [
10935           buf _ (buf copyFrom: 0 to: cur_pos ) , ch printString , (buf copyFrom: cur_pos to: buf size ).
10936           cur_pos _ cur_pos + 1
10937         ] ifFalse: [
10938           sc = 14 ifTrue:[
10939             buf removeAt: cur_pos - 1 .
10940             cur_pos _ cur_pos - 1
10941           ] . 
10942         ]
10943       ] .
10944   'TODO ask nroot to fix self in blocks' .
10945       view_pos _ (
10946          (cur_pos min: view_pos ) min: (self getWidth / 8 )
10947       ) max: 0 .
10948       cur_pos _ (cur_pos min: buf size ) max: 0 .
10949     ].
10950    ^ self
10951   
10952 
10953                                    setOnEnter
10954   
10955   setOnEnter: e=CFrogBlock ->* || on_enter _ e 
10956 
10957                                   setOnEscape
10958   
10959   setOnEscape: bl=CFrogBlock ->* || on_escape _ bl 
10960 
10961                                       run
10962   
10963   run: cb=CFrogBlock ->*
10964   |
10965   |
10966     text_bar _ CUITextBar new .
10967   
10968     background _ CUIBackground new .
10969     background -> bg_color _ #color_DKGRAY .
10970     background->sz_y _ 24 .
10971     background->sz_x _ 250 .
10972     background->x _ 640 - background->sz_x /2 .
10973     background->y _ 480 - background->sz_y /2 .
10974   
10975     text_bar->sz_y _ 12 .
10976     text_bar->sz_x _ 250-24 .
10977     text_bar->x _ 12 .
10978     text_bar->y _ 16 .
10979     text_bar focus .
10980   
10981     
10982   
10983     background addChild: text_bar .
10984     background addChild: label .
10985   
10986 
10987                                   CONSTRUCTOR
10988   
10989   init
10990   |
10991     label=CUILabel
10992   |
10993     on_init _ [
10994       text_bar _ CUITextBar new .
10995   
10996       background _ CUIBackground new .
10997       background -> bg_color _ #color_DKGRAY .
10998       background->sz_y _ 24 .
10999       background->sz_x _ 250 .
11000       background->x _ 640 - background->sz_x /2 .
11001       background->y _ 480 - background->sz_y /2 .
11002   
11003       text_bar->sz_y _ 12 .
11004       text_bar->sz_x _ 250-24 .
11005       text_bar->x _ 12 .
11006       text_bar->y _ 16 .
11007       text_bar focus .
11008   
11009       text_bar setOnEnter: [:v=CFrogStr|
11010         cb value: v .
11011         exited _ 1 . 
11012       ] .
11013     
11014       background addChild: text_bar .
11015   
11016       (title hasClass: CFrogStr) ifTrue: [
11017         label _ CUILabel new .
11018         label setLabel: title. 
11019         label->x _ 4 .
11020         label->y _ 4 .
11021         background addChild: label .
11022       ]  ifFalse: [
11023         background->sz_y _ 16 .
11024         text_bar->y _ 2 .
11025       ]
11026   
11027       #ui_root _ background .
11028   
11029     ] .
11030   
11031     draw_it_name _ 'Draw3DWorld'.
11032     on_refresh _ [] .
11033     on_event _ [:v=CUIEvent |
11034       v->type = 'KeyDown' ifTrue: [
11035         'CH_ESC' .
11036         v->m1 = 27 ifTrue: [
11037           exited _  1.
11038         ] .
11039        'CH_SHIFT_ESC' .
11040         v->m1 = 28 ifTrue: [
11041           exited _ 1 .
11042         ] .
11043         exited ifFalse: [
11044          #ui_root sendEventToUI: v .
11045   
11046         ].
11047       ].
11048     ].
11049      ^ self
11050   
11051 
11052                                       run
11053   
11054   run: cb=CFrogBlock ->*
11055   |
11056   |
11057     text_bar _ CUITextBar new .
11058   
11059     background _ CUIBackground new .
11060     background -> bg_color _ #color_DKGRAY .
11061     background->sz_y _ 24 .
11062     background->sz_x _ 250 .
11063     background->x _ 640 - background->sz_x /2 .
11064     background->y _ 480 - background->sz_y /2 .
11065   
11066     text_bar->sz_y _ 12 .
11067     text_bar->sz_x _ 250-24 .
11068     text_bar->x _ 12 .
11069     text_bar->y _ 16 .
11070     text_bar focus .
11071   
11072     
11073   
11074     background addChild: text_bar .
11075     background addChild: label .
11076   
11077 
11078                                   CONSTRUCTOR
11079   
11080   init | |
11081     sub_elems _ #() .
11082    ^ self
11083   
11084 
11085                                    rearrange
11086   
11087   rearrange ->* 
11088   |
11089     yy=CFrogNum
11090     button=CUIButton
11091     pair=CFrogArray
11092     elem=CUIElem
11093   |
11094     sub_elems _ #() .
11095     yy _ 10 . 
11096     0 to: sub_elems2 size do:[:w=CFrogNum|
11097       button _ sub_elems2 at: w .
11098       self addChild: button .
11099       button->y _ yy .
11100       pair _ button -> user_data .
11101       elem _ (pair at: 1 ) .
11102       (pair at: 2) ifTrue: [
11103         self removeChild: elem .
11104         self addChild: elem .
11105         elem->x _ 20 .
11106         elem->y _ yy + 15 .
11107         sz_x _ sz_x max: 20 + (elem->sz_x max: button ->sz_x ) .
11108         yy _ yy + elem -> sz_y + 30 .
11109       ] ifFalse: [
11110         self removeChild: elem .
11111         sz_x _ sz_x max: 20 +  button -> sz_x .
11112         yy _ yy + 30 .
11113       ] .
11114       sz_y _ yy .
11115     ] .
11116     parent rearrange .
11117 
11118                                   setBracnhes
11119   
11120   setBranchLabels: l=CFrogArray withElements: e=CFrogArray
11121   ->*
11122   |
11123     button=CUIButton
11124     pairs=CFrogArray
11125     y=CFrogNum
11126     rearrange=CFrogBlock
11127     pair=CFrogArray 
11128     elem=CUIElem
11129     elem2=CUIElem
11130     prefixes=CFrogDictionary
11131     at=CFrogNum
11132     prefix=CFrogStr
11133     subtree=CUITree
11134     l2=CFrogArray
11135     e2=CFrogArray
11136     tmp=CFrogArray
11137   |
11138     y _ 10 .
11139     pairs _ #() .
11140     sub_elems2 _ #() .
11141     sub_trees _ #() .
11142     
11143   
11144     0 to: l size do: [:i=CFrogNum |
11145       '#(labelelemnt open)' .
11146       pairs add: #((l at: i ) (e at: i) (0))
11147     ] .
11148     'Compute a/b/c prefixes,make a list without sub-entries' .
11149     prefixes _ CFrogDictionary new .
11150     tmp _ #(). 
11151     pairs do: [:p=CFrogArray |
11152       at _ p first indexOf: '/' .
11153       at > 0 ifTrue: [
11154         prefix _ p first copyFrom: 0 to: at .
11155         ((prefixes at: prefix) hasClass: CFrogArray) ifTrue: [
11156           (prefixes at: prefix) add: p .
11157         ] ifFalse: [
11158           prefixes at: prefix put: #( p ) 
11159         ] .
11160       ] ifFalse: [
11161         tmp add:  p .
11162       ] .
11163     ] .
11164   
11165     pairs _ tmp .
11166   
11167     prefixes doKeys: [:k=CFrogStr|
11168       subtree _ CUITree new.
11169       pair _ prefixes at: k .
11170       l2 _ pair collect: [:d=CFrogArray| 
11171         'Copy without prefix/' .
11172         d first copyFrom: k size + 1  to: d first size
11173       ] .
11174       e2 _ pair collect: [:d=CFrogArray| d at: 1 ] .
11175       subtree setBranchLabels: l2 withElements: e2 .
11176       subtree rearrange .
11177   
11178       'Hack alert,Make sure expected elments appear with items with subtrees' .
11179       elem _ subtree .
11180       0 to: l size do:[:poo=CFrogNum |
11181         (l at: poo) = k ifTrue: [
11182           elem _ CUIElem new .
11183           elem2 _ e at: poo .
11184           elem -> sz_y _ subtree -> sz_y +  elem2 -> sz_y + 20 .
11185           elem -> sz_x _ subtree->sz_x max: elem2->sz_x .
11186           elem addChild: elem2 .
11187           elem2->y _ 0 .
11188           subtree->y _ elem2->sz_y + 20 .
11189           elem addChild: subtree.   
11190         ] .
11191       ]. 
11192   
11193   'Used with rearrange' .
11194       subtree->parent _ self .
11195   
11196       pairs _ pairs reject: [:p=CFrogArray|
11197        'Remove old entry to avoid 2 names per tree' .
11198         p first  = k
11199       ] .
11200   
11201       pairs add: #( (k)  (elem) (0) ) .
11202     ] .
11203   
11204     pairs sort: [:a* :b*|
11205       a first compare: b first 
11206     ] .  
11207   
11208     
11209   
11210     pairs do: [:p=CFrogArray |
11211      button _ CUIButton new .
11212      button -> bg_color _ #color_YELLOW .
11213      button -> fg_color _ #color_RED .
11214      button -> sz_y _ 12 .
11215      button -> sz_x _ 100 .
11216      button -> x _ 20 .
11217      button -> y _ 0 .
11218      button->user_data _ p .
11219      button->label _ '+] ',  p first copy .
11220      button onLeftUp: [ :button=CUIButton |
11221        button show .
11222        'lup' show .
11223       button->label show .
11224        p _ button ->user_data. 
11225        p show .
11226        (p at: 2 ) = 0 ifTrue: [
11227          button->label _ '-] ',  p first copy .
11228          button->bg_color _ #color_LTPURPLE .
11229          p at: 2 put: 1 .
11230          self addChild: (p at: 1) .
11231        ] ifFalse: [
11232          button->label _ '+] ',  p first copy .
11233          button->bg_color _ #color_YELLOW .
11234          self removeChild: (p at: 1) .
11235          p at: 2 put: 0 .
11236        ] .
11237        self rearrange .
11238       ] .
11239       sub_elems2 add: button .
11240     ] .
11241   
11242     self rearrange.
11243   
11244 
11245                                   CONSTRUCTOR
11246   
11247   init | |
11248     self setGraphics: 'GR/Uzi/Idle' .
11249     max_ammo _ 100 . 
11250     ammo _ 25 .
11251     x _ 0 .
11252     y _ 300 .
11253     xoff _ 0 .
11254     yoff _ 0 .
11255     timeout _ 0 .
11256   
11257     state _ 'Normal' .
11258   
11259     inventory_item _ CUIGridItem new .
11260     inventory_item setGraphics: 'GR/Uzi/Icon' .
11261     inventory_item setCount: ammo .
11262     inventory_item setItem: self .
11263     inventory_item ->name _
11264   'Uzi
11265   Spray some motherfuckers
11266   21 gansta shit 
11267   ' .
11268     inventory_item onLeftUp: [
11269       #world getPlayer selectItem: self .
11270     ] .
11271     #world getPlayer addInventoryItem: inventory_item .
11272     ^ self
11273   
11274 
11275                                     animate
11276   
11277   animate ->* | cur_ts=CFrogNum |
11278     cur_ts _ CFrogTime now asSeconds .
11279     inventory_item setCount: ammo  .
11280     timeout < cur_ts ifTrue: [
11281   
11282       state = 'Fire' ifTrue: [
11283         timeout + .2 < cur_ts ifTrue: [
11284           state _ 'Reload' .
11285           timeout _ cur_ts + .75 .
11286         ] ifFalse: [
11287           ^ 0 .
11288         ] .
11289       ] .
11290       state = 'Reload' ifTrue: [
11291         anim_no_repeat _ 1 .
11292         anim_start_tS _ cur_ts .
11293         self setGraphics: 'GR/Uzi/Reload' .
11294         timeout < cur_ts ifTrue: [
11295           state _ 'Normal' .
11296         ] .
11297   
11298       ] .
11299      
11300       state = 'Normal' ifTrue: [
11301         anim_no_repeat _ 0 .
11302         self setGraphics: 'GR/Uzi/Idle' .
11303       ].
11304     ] 
11305 
11306                                       fire
11307   
11308   fire ->* |
11309    cur_ts=CFrogNum
11310    player=CPlayer
11311    canidates=CFrogArray 
11312    wall_hole=CWallStain
11313    case*
11314    sz=CFrogNum
11315    floor_stain=CFloorStain
11316    best_thing*
11317    w=C3DWorldManager
11318    dmg=CFrogNum
11319    |
11320     w _ #world .
11321     player _ w getPlayer .
11322     ammo ifTrue: [
11323      
11324       cur_ts _ CFrogTime now asSeconds .
11325   
11326       ((state = 'Normal' or: state = 'Fire' ) and: timeout < cur_ts) ifTrue: [
11327         state = 'Normal' ifTrue: [
11328           anim_no_repeat _ 0 .
11329           anim_start_tS _ cur_ts .
11330           self setGraphics: 'GR/Uzi/Fire' .
11331         ] .
11332         state _ 'Fire' .
11333         case _ CShellCasing new .
11334         case setGraphics: 'GR/GUN1/BULLET' .
11335         case ejectAtX: x atY: y .
11336         player addShellCasing: case .
11337         w noiseSoundForTime: 1000/10. withMin: 42 withMax: 52 .
11338         sz _ w screenCoordToZ .
11339   
11340         timeout _ cur_ts + (1./10) .
11341         ammo _ ammo - 1 max: 0 .
11342         inventory_item setCount: ammo .
11343         dmg _ 5 * CFrogRandom new next + 3 .
11344         player rangeAttackAtAngle: player->angle withDamage: dmg .
11345   
11346         CWallStain newStainAtX: w screenCoordToX atY: w screenCoordToY atZ: w screenCoordToZ
11347           withGraphicsLump: 'GR/GUN1/BULLET_HOLE' withSpread: 16 .
11348   
11349       ] .
11350     ] .
11351   
11352     ammo = 0 ifTrue: [
11353       player removeItem: inventory_item .
11354     ] .
11355   
11356 
11357                                   CONSTRUCTOR
11358   
11359   init | |
11360     count _ 30  .
11361     #world addThing: self .
11362     item_class _ CUzi .
11363     template _ #world getThingTemplate: 'CUziPickup' .
11364     ^ self
11365   
11366 
11367                                   CONSTRUCTOR
11368   
11369   init | |
11370     self setGraphics: 'GR/GUN1/BULLET_HOLE' .
11371     ^ self
11372   
11373 
11374                                     getSide
11375   
11376   getSide ->CFrogNum || ^ side
11377 
11378                                     getTileX
11379   
11380   getTileX ->CFrogNum | | ^ tile getXPos
11381 
11382                                     getTileY
11383   
11384   getTileY -> CFrogNum || ^ tile getYPos
11385 
11386                                 newFromDirection
11387   
11388   placeAtAngle: a=CFrogNum
11389     fromX: xx=CFrogNum
11390     fromY: yy=CFrogNum
11391     atHeight: zz=CFrogNum
11392     ->*
11393   |
11394     X=CFrogNum
11395     Y=CFrogNum
11396     rando=CFrogRandom
11397     h=CFrogNum
11398     seg=CFrogNum
11399     door_offset=CFrogNum
11400     door=CDoorx
11401   |
11402    'TODO' .
11403     ^ 0 
11404 
11405                                    placeAtXYZ
11406   
11407   
11408 
11409                                putGraphicsAtXatY
11410   
11411   
11412 
11413                                   CONSTRUCTOR
11414   
11415   init -> CWaterPickup ||
11416     count _ 20  .
11417     #world addThing: self .
11418     item_class _ CFrogDick .
11419     template _ #world getThingTemplate: 'CWaterPickup' .
11420     ^ self
11421 
11422                                   CONSTRUCTOR
11423   
11424   init: idx=CFrogNum ->* | |
11425     max_ammo _ 0 . 
11426     ammo _ 0 .
11427     x _ 0 .
11428     y _ 300 .
11429     xoff _ 0 .
11430     yoff _ 0 .
11431     timeout _ 0 .
11432   
11433     wall_size _ 1 .
11434   
11435     inventory_item _ CUIGridItem new .
11436     inventory_item setItem: self .
11437     inventory_item onLeftUp: [
11438       #world getPlayer selectItem: self .
11439     ] .
11440     self animate . 'Update inventory item '.
11441   
11442    'SetBlockIdx sets greaphgics for us' .
11443     (self setBlockIndex: idx) ifTrue: [
11444       tile_idx _ idx .
11445       #world getPlayer addInventoryItem: inventory_item .
11446       ^ self
11447     ] .
11448   
11449   
11450     ^ 0 
11451   
11452 
11453                                   afterRestore
11454   
11455   addToPlayerAgain:p=CPlayer ->* |
11456     who=CUIGrid
11457   |
11458     in_quick_inventory ifTrue: [
11459       who _ p->quick_inventory
11460     ] ifFalse: [
11461       who _ p->main_inventory
11462     ] .
11463   
11464     inventory_item _ CUIGridItem new .
11465     inventory_item setCount: ammo .
11466     inventory_item setItem: self .
11467     inventory_item onLeftUp: [
11468       #world getPlayer selectItem: self .
11469     ].
11470   
11471     p->items add: self .
11472   
11473   
11474     who addItem: inventory_item atX: grid_x atY: grid_y .
11475   
11476     self setBlockIndex: tile_idx .
11477 
11478                                     altFire
11479   
11480   altFire ->* |
11481    w=C3DWorldManager
11482    cur_ts=CFrogNum
11483    wz=CFrogNum
11484    wx=CFrogNum
11485    wy=CFrogNum
11486    dist=CFrogNum
11487    a=CFrogNum
11488    player=CPlayer
11489    rem=CFrogNum
11490     tile=C3DPoint
11491    |
11492     w _ #world .
11493     cur_ts _ CFrogTime now asSeconds .
11494     timeout < cur_ts ifTrue: [
11495       timeout _ cur_ts + .1 .
11496   
11497   
11498       tile _ w screenTile .
11499       wx _ tile->x.
11500       wy _ tile->y.
11501       wz _ tile->z.
11502   
11503       w setTile: 0 atX: wx  atY: wy  atZ: wz .
11504       w->is_client ifTrue: [
11505         #client sendPlaceBlock: 0 atX: wx atY: wy  atZ: wz 
11506       ] .
11507     ] .
11508 
11509                                     animate
11510   
11511   animate->*
11512   |
11513   |
11514     inventory_item setCount: wall_size .
11515   'wall_size ' show .
11516     wall_size show .
11517   
11518 
11519                                       fire
11520   
11521   fire ->* |
11522    w=C3DWorldManager
11523    cur_ts=CFrogNum
11524    wz=CFrogNum
11525    wx=CFrogNum
11526    wy=CFrogNum
11527    dist=CFrogNum
11528    a=CFrogNum
11529    player=CPlayer
11530    tile=C3DPoint
11531    side=C3DPoint
11532    |
11533     w _ #world .
11534     cur_ts _ CFrogTime now asSeconds .
11535     timeout < cur_ts ifTrue: [
11536       timeout _ cur_ts + .1 .
11537   
11538       tile _ w screenTile .
11539       side _ w screenTileSide. 
11540       wx _ tile->x + side->x .
11541       wy _ tile->y + side->y .
11542       wz _ tile->z + side->z .
11543   
11544       0 to: wall_size do: [:o=CFrogNum|
11545         w setTile: tile_idx atX: wx atY: wy atZ: wz + o .
11546   
11547         w->is_client ifTrue: [
11548           #client sendPlaceBlock: tile_idx atX: wx atY: wy atZ: wz + o 
11549         ] .
11550       ] .
11551     ] .
11552 
11553                                  setBlockIndex
11554   
11555   setBlockIndex: i=CFrogNum
11556     ->CFrogNum
11557   |
11558     t=CTileTemplate
11559   |
11560     tile_idx _ i .
11561     t _ #world->tile_templates at: i .
11562     (t hasClass: CTileTemplate) ifTrue: [
11563        self setGraphics: t->wall_texture->name .
11564        ^ 1 .
11565     ] .
11566     ^ 0 .
11567   
11568 
11569                                   CONSTRUCTOR
11570   
11571   init: names=CFrogStr ->* | |
11572     name _ names .
11573     max_ammo _ 0 . 
11574     ammo _ 0 .
11575     x _ 0 .
11576     y _ 300 .
11577     xoff _ 0 .
11578     yoff _ 0 .
11579     timeout _ 0 .
11580     inventory_item _ CUIGridItem new .
11581     inventory_item setCount: ammo .
11582     inventory_item setItem: self .
11583     inventory_item onLeftUp: [
11584       'poo ' show.
11585       #world getPlayer selectItem: self .
11586     ] .
11587   
11588     ((#world getThingTemplate: name) hasClass: C3DThingTemplate) ifTrue: [
11589       #world getPlayer addInventoryItem: inventory_item .
11590       'Update graphics for us'.
11591       self animate .
11592       ^ self
11593     ] .
11594     ^ 0 
11595   
11596 
11597                                     animate
11598   
11599   animate->*
11600   |
11601    t=C3DThingTemplate 
11602   |
11603     t _ #world getThingTemplate: name .
11604     inventory_item ->cnt _ tag .
11605     (t hasClass: C3DThingTemplate) ifTrue: [
11606       self setGraphics :  t->front->name  .
11607     ] .
11608 
11609                                       fire
11610   
11611   fire ->* |
11612    w=C3DWorldManager
11613    cur_ts=CFrogNum
11614    wz=CFrogNum
11615    wx=CFrogNum
11616    wy=CFrogNum
11617    dist=CFrogNum
11618    a=CFrogNum
11619    player=CPlayer
11620    thing*
11621    |
11622     w _ #world .
11623     cur_ts _ CFrogTime now asSeconds .
11624     timeout < cur_ts ifTrue: [
11625       timeout _ cur_ts + .1 .
11626       wz _ w screenCoordToZ .
11627       wx _ w screenCoordToX .
11628       wy _ w screenCoordToY .
11629   'move 32 unit backwards to set closer block' .
11630       player _ w getPlayer .
11631       dist _ ((wx - player->x) squared + (wy - player->y) squared) sqrt - 32 max: 0 .
11632   
11633       dist > (7 * 128) ifTrue: [
11634         ^ 0 .
11635       ]
11636       (wz - player->z) abs > 7 ifTrue: [
11637         ^ 0
11638       ] .
11639   
11640       a _ wx - player->x arg: wy - player->y .
11641       wx _ player->x + (a cos * dist ) . 
11642       wy _ player->y + (a sin * dist ) .
11643       thing _ (CFrogClass fromString: name) new  .
11644       thing->x _ wx .
11645       thing->y _ wy .
11646       thing->z _ wz . 
11647       thing->activate_tag _ tag .
11648   
11649       w->is_client ifTrue: [
11650         #client sendPlaceThing: (CFrogClass fromString: name) atX: wx atY: wy atZ: wz withActivateTag: tag . 
11651       ] .
11652   
11653   
11654     ] .
11655 
11656                                   CONSTRUCTOR
11657   
11658   init | |
11659     #world addThing: self .
11660     speed _ 64 / 30 * 2 .
11661     health _ 40 .
11662     random_generator _ CFrogRandom new .
11663     template _ #world getThingTemplate: 'CZombie' .
11664     animation_start_tS _ 0 .
11665     state _ 'Normal' . 
11666     piss_stream _ CPissStream new .
11667     no_fall_off_edge _ 1 .
11668     piss_stream ->from _ self .
11669     ^ self
11670   
11671 
11672                                   afterRestore
11673   
11674   
11675 
11676                                     animate
11677   
11678   animate ->* ||
11679     piss_stream update
11680 
11681                                    damagefrom
11682   
11683   damage: amt=CFrogNum from: t=C3DThing ->* | |
11684     'blood' .
11685     1 to: amt / 6 + 5 do:[ 
11686       #world newParticleAtX: x atY: y atZ: z + .5 withSpread: 64 withColor: #color_RED 
11687     ] .
11688    
11689     target _ t .
11690   
11691     self damage: amt .
11692   
11693     self update . 
11694 
11695                                 pissTowardsThing
11696   
11697   pissTowardsThing: who=C3DThing ->*
11698   |
11699     piss=CPissLink
11700     cur_ts=CFrogNum
11701     rand=CFrogRandom
11702     launch_angle=CFrogNum
11703     targetd=CFrogNum
11704     force=CFrogNum
11705     a=CFrogNum
11706     base_a=CFrogNum
11707     approx=CFrogBlock
11708     best_force=CFrogNum
11709     hit_at=CFrogArray
11710     old_hit_at=CFrogArray
11711     best_force_d=CFrogNum
11712     d=CFrogNum
11713     cap=CFrogNum
11714   |
11715     piss_stream update .
11716     cur_ts _ CFrogTime now asSeconds .
11717   
11718   
11719     approx _ [ :percent=CFrogNum|
11720       piss _ CPissLink new .
11721       piss ->x _  x + (16 * a cos ) .
11722       piss ->y _  y + (16 * a sin ) .
11723       piss ->z _  z + .3 .
11724       piss ->momx _ (force * percent * a cos).
11725       piss ->momy _ (force * percent * a sin).
11726       piss ->momz _ .35 .
11727       piss->from _ self .
11728       
11729       cap _ 0 .
11730       [
11731         hit_at _ piss updateWithWeight: 3  makeParticles: 0 .
11732         hit_at = 1 and: cap < 15
11733       ] whileTrue: [
11734         cap _ cap + 1 .
11735       ] .
11736       d _ (((hit_at at: 0) -  x ) squared + ((hit_at at: 1) -  y ) squared ) sqrt .
11737       ( targetd - d ) abs < best_force_d ifTrue: [
11738         best_force _ force * percent .
11739         best_force_d _ d 
11740       ]
11741     ] .
11742   
11743     cur_ts  >= next_piss_tS ifTrue: [
11744       rand _ CFrogRandom new .
11745       next_piss_tS _ next_piss_tS + .3 .
11746       'https://en.wikipedia.org/wiki/Trajectory' .
11747       launch_angle _ .35 arctan .
11748       targetd _  ((who ->x -  x ) squared + (who ->y -  y ) squared ) sqrt . 
11749       targetd _ targetd - 8 max: 0 .
11750       force _ targetd / 5 min: 24 .
11751       best_force _ force .
11752       best_force_d _ 10000. .
11753   
11754       base_a _ (who ->x -  x) arg: (who ->y -  y ) .
11755       a _  base_a + (3.14 / 100 * rand next ) .
11756   
11757       0 to: 5 do: [:m=CFrogNum|
11758         approx value: (m + 5) / 5 .
11759       ] .
11760   
11761   'Graduall piss towards target  ' .
11762       force _ (((cur_ts - state_start_tS) * 3.14 / 1.5  min: 3.14) sin + .2 min: 1)
11763          * best_force min: 24 .
11764   
11765       0 to: 3 do: [:v=CFrogNum |
11766           piss _ CPissLink new .
11767           piss ->x _  x + (16 * a cos ) .
11768           piss ->y _  y + (16 * a sin ) .
11769           piss ->z _  z + .3 .
11770           piss ->momx _ (force * a cos).
11771           piss ->momy _ (force * a sin).
11772           piss ->momz _ .35 .
11773           piss->from _ self .
11774           (piss updateWithWeight:  1  / 3 * ( 3 -  v)  makeParticles: 0) ifTrue: [ 
11775             'test if wee havent hit the ground '.
11776             piss_stream addLink: piss .
11777           ]
11778       ] .
11779     ] .
11780 
11781                                      update
11782   
11783   update -> * |
11784     player=CPlayer
11785     cur_tS=CFrogNum
11786     dist=CFrogNum
11787     new_t=C3DThingTemplate
11788     hit_wall=CFrogNum
11789     w=C3DWorldManager
11790   |
11791     w _ #world .
11792     health <= 0 ifTrue: [
11793       state ~= 'Dead' ifTrue: [
11794         template  _ #world getThingTemplate: 'CZombie/Dead' .
11795         w sweepSoundForTime: 300 withMin: 30 withMax: 20 .
11796         state _ 'Dead' .
11797         self die .
11798         animation_start_tS _ CFrogTime now asSeconds .
11799         animation_no_repeat _ 1 .
11800       ] .
11801       ^ 1 .
11802     ] .
11803   
11804     cur_tS _ CFrogTime now asSeconds .
11805     player _ self lookForTarget .  
11806   
11807     (target hasClass: C3DThing) ifFalse: [
11808       target _ player
11809     ] .
11810   
11811   'Check if close enough to bite'.
11812     state = 'Chase' ifTrue: [
11813       dist _ ((target ->x - x ) squared + (target ->y - y) squared ) sqrt .
11814       dist < (1.5 * 128) ifTrue: [
11815         w noiseSoundForTime: 300 withMin:30 withMax: 40 .
11816         state _ 'Bite' .
11817         state_start_tS _ cur_tS .
11818         state_duration _ 1 .
11819         animation_start_tS _ CFrogTime now asSeconds .
11820         animation_no_repeat _ 1 .
11821         template _ #world getThingTemplate: 'CZombie/Bite' .
11822         target damage: random_generator next * 43 + 7 from: self .
11823       ] .
11824     ] .
11825   
11826     state = 'Bite' ifTrue: [
11827       ( cur_tS - state_start_tS ) >= state_duration  ifTrue: [
11828         state _ 'Chase' .
11829       ] ifFalse: [
11830         ^ 1 .
11831       ] .
11832     ] .
11833   
11834     state = 'Piss' ifTrue: [
11835       (cur_tS - state_start_tS) >= state_duration ifTrue: [
11836         state_start_tS _ cur_tS .
11837         state_duration _ 0 . 
11838         state _ 'Chase' .
11839         w sweepSoundForTime: 600 withMin: 57 withMax: 50 .
11840       ] ifFalse: [
11841         template _ #world getThingTemplate: 'CZombie/Piss' .
11842         self pissTowardsThing: target .
11843         ^ 1 .
11844       ] .
11845     ] .
11846   
11847     ( cur_tS - state_start_tS ) >= state_duration  ifTrue: [
11848       'Piss? after chasing'
11849       (state = 'Chase'  and: (random_generator next < (3 / 10 ))) ifTrue: [
11850         w sweepSoundForTime: 600 withMin: 50 withMax: 57 .
11851         state _ 'Piss' .
11852         template _ #world getThingTemplate: 'CZombie/Piss' .
11853         state_start_tS _ cur_tS .
11854         state_duration _ 2 . 
11855         self pissTowardsThing: target .
11856         ^ 1 .
11857       ] .
11858   
11859       ((self canSeeThing:  target) and: state ~= 'Chase') ifTrue: [
11860         state _ 'Chase' .
11861         state_duration _ random_generator next * 2 + .5 .
11862         angle _ ((target ->x - x ) arg: (target ->y - y )) .
11863         template _ #world getThingTemplate: 'CZombie' .
11864       ] ifFalse: [
11865         state _ 'Normal' .
11866       ] .
11867     ] .  
11868   
11869     state = 'Chase' ifTrue: [   
11870       speed _ 64 / 30 * 3 .
11871     ] .
11872   
11873   
11874     state = 'Normal' ifTrue: [
11875        speed _ 64 / 30  * 1.5 . 
11876     ] .  
11877   
11878   
11879   
11880     'Walk around ' .
11881   
11882     template _ #world getThingTemplate: 'CZombie' .
11883     animation_no_repeat _ 0 .
11884   
11885     self wander: speed withJumpVelocity: .55 withTarget: target .
11886   
11887     'Jump Randomly' .
11888   
11889     self isOnGround ifTrue: [
11890        random_generator next < (.9 / 10) ifTrue: [
11891          momz _ #world gravity * 3 .
11892        ]
11893     ] .
11894   
11895     self isOnGround ifTrue: [just_jumped _ 0  ] .
11896   
11897 
11898                                       Edit
11899   
11900   new | |
11901    ^ self basicNew
11902   
11903 
11904                                       Edit
11905   
11906   new | |
11907    ^ self basicNew
11908   
11909 
11910                                       Edit
11911   
11912   new | |
11913    ^ self basicNew
11914   
11915 
11916                                       Edit
11917   
11918   new | |
11919    ^ self basicNew init
11920   
11921 
11922                                       Edit
11923   
11924   new | |
11925    ^ self basicNew init
11926   
11927 
11928                                       Edit
11929   
11930   new | |
11931    ^ self basicNew init
11932   
11933 
11934                                       Edit
11935   
11936   new | |
11937    ^ self basicNew init
11938 
11939                                       Edit
11940   
11941   newFromStream: s | |
11942    ^ self basicNew initFromStream: s 
11943   
11944 
11945                                       Edit
11946   
11947   new | tmp|
11948    tmp _ self basicNew init .
11949    ^ tmp .
11950   
11951 
11952                                       Edit
11953   
11954   new ->*
11955   |
11956   |
11957     ^ self basicNew init . 
11958 
11959                                       Edit
11960   
11961   new | |
11962    ^ self basicNew init
11963   
11964 
11965                                       Edit
11966   
11967   new | |
11968    ^ self basicNew init
11969   
11970 
11971                                       Edit
11972   
11973   new | |
11974    ^ self basicNew init
11975   
11976 
11977                                       Edit
11978   
11979   newFromStream:s* | |
11980    ^ self basicNew initFromStream: s
11981   
11982 
11983                                       Edit
11984   
11985   newServerAt: a=CFrogStr atPort: p=CFrogNum
11986   ->*
11987   |
11988   |
11989     ^ self basicNew initServerAt: a atPort: p . 
11990 
11991                                       Edit
11992   
11993   newConnectionTo: a=CFrogStr atPort: p=CFrogNum
11994   ->* 
11995   |
11996   |
11997     a show .
11998     ^ self basicNew initConnectionTo: a atPort: p .
11999 
12000                                       Edit
12001   
12002   new | |
12003    ^ self basicNew init
12004   
12005 
12006                                       Edit
12007   
12008   new | |
12009    ^ self basicNew init
12010   
12011 
12012                                       Edit
12013   
12014   new | |
12015    ^ self basicNew init
12016   
12017 
12018                                       Edit
12019   
12020   new | |
12021    ^ self basicNew init
12022 
12023                                       Edit
12024   
12025   new | |
12026    ^ self basicNew init
12027   
12028 
12029                                       Edit
12030   
12031   new | |
12032    ^ self basicNew init
12033   
12034 
12035                                       Edit
12036   
12037   new | |
12038    ^ self basicNew init
12039   
12040 
12041                                       Edit
12042   
12043   new | |
12044    ^ self basicNew init
12045   
12046 
12047                                       Edit
12048   
12049   new | |
12050    ^ self basicNew init
12051   
12052 
12053                                       Edit
12054   
12055   new | |
12056    ^ self basicNew init
12057   
12058 
12059                                       Edit
12060   
12061   new | |
12062    ^ self basicNew init
12063   
12064 
12065                                       Edit
12066   
12067   new | |
12068    ^ self basicNew init
12069   
12070 
12071                                       Edit
12072   
12073   new | |
12074    ^ self basicNew init
12075   
12076 
12077                                       Edit
12078   
12079   new->CEliza | |
12080    ^ self basicNew init 
12081 
12082                                       Edit
12083   
12084   makeResponsesFromArray: array=CFrogArray |
12085     reasm=CElizaReasm
12086     input=CFrogString
12087     result*
12088     idx=CFrogNum
12089     ret=CEliza
12090   |
12091     ret _ CEliza new.
12092     ret setHello: (array at: 0) .
12093     idx _ 1 .
12094     [idx < array size ] whileTrue: [
12095       input _ array at: idx .
12096       result _ array at: idx + 1 .
12097       (result hasClass: CFrogArray ) ifTrue: [
12098          result _ CEliza makeResponsesFromArray: result .
12099          reasm _ CElizaReasm new .
12100          ret addReasm: reasm .
12101          reasm initFromString: input .
12102          reasm setResult: result .
12103       ] .
12104       (result hasClass: CFrogStr ) ifTrue: [
12105          reasm _ CElizaReasm new .
12106          ret addReasm: reasm .
12107          reasm initFromString: input .
12108          reasm setResult: result .
12109       ] .
12110       (result hasClass: CFrogBlock ) ifTrue: [
12111          reasm _ CElizaReasm new .
12112          ret addReasm: reasm .
12113          reasm initFromString: input .
12114          reasm setResult: result .
12115       ] .
12116       idx _ idx + 2
12117     ] .
12118     ^ ret
12119 
12120                                       Edit
12121   
12122   new ->CElizaReasm | |
12123    ^ self basicNew init
12124 
12125                                       Edit
12126   
12127   new | |
12128    ^ self basicNew init
12129   
12130 
12131                                       Edit
12132   
12133   new:t=C3DThing | |
12134    ^ self basicNew init:t
12135   
12136 
12137                                       Edit
12138   
12139   new | |
12140    ^ self basicNew init
12141   
12142 
12143                                       Edit
12144   
12145   new | |
12146    ^ self basicNew init
12147   
12148 
12149                                       Edit
12150   
12151   new | |
12152    ^ self basicNew init
12153   
12154 
12155                                       Edit
12156   
12157   new ->CFloorStain | |
12158    ^ self basicNew init
12159 
12160                                       Edit
12161   
12162   getTileX || ^ tile_x
12163 
12164                                       Edit
12165   
12166   new -> CFrogArray | |
12167     ^ #( )
12168    
12169 
12170                                       Edit
12171   
12172   new | |
12173    ^ self basicNew
12174   
12175 
12176                                       Edit
12177   
12178   new:name ||
12179     ^ self basicNew init: name
12180 
12181                                       Edit
12182   
12183   new | |
12184    ^ self basicNew
12185   
12186 
12187                                       Edit
12188   
12189   new | |
12190    ^ self basicNew
12191   
12192 
12193                                       Edit
12194   
12195   new | |
12196    ^ self basicNew
12197   
12198 
12199                                       Edit
12200   
12201   new ->CFrogDick | |
12202    ^ self basicNew init
12203   
12204 
12205                                       Edit
12206   
12207   new->CFrogDictionary | |
12208    ^ self basicNew init
12209   
12210 
12211                                       Edit
12212   
12213   new | |
12214    #error_msg _ 'Divide error' .
12215    ^ self basicNew
12216   
12217 
12218                                       Edit
12219   
12220   new: msg | |
12221     #error_msg _ msg .
12222     ^ self basicNew
12223   
12224 
12225                                       Edit
12226   
12227   new | |
12228    ^ self basicNew init
12229   
12230 
12231                                       Edit
12232   
12233   get: name=CFrogStr  -> CFrogImg
12234   |
12235     has=CFrogImg 
12236   |
12237     (#img_table hasClass: CFrogDictionary ) ifFalse: [
12238       #img_table _ CFrogDictionary new .
12239     ].
12240     has _ #img_table at: name .
12241     (has hasClass: CFrogImg) ifFalse: [
12242       has _ CFrogImg new .
12243       has setGraphics: name . 
12244       #img_table at: name put: has .
12245     ]
12246     ^ has .
12247 
12248                                       Edit
12249   
12250   new ->CFrogNPC | |
12251    ^ self basicNew init
12252   
12253 
12254                                       Edit
12255   
12256   asspoodle || ^ 0
12257   
12258 
12259                                       Edit
12260   
12261   new ->CFrogRandom | |
12262     #rand_gen isNil ifFalse: [
12263       ^ self basicNew init: #rand_gen next
12264     ] .
12265     #rand_gen _ self basicNew init: 123
12266     ^ self basicNew init: 1
12267   
12268 
12269                                       Edit
12270   
12271   new: seed2=CFrogNum ->CFrogRandom | |
12272     ^ self basicNew init: seed2
12273 
12274                                       Edit
12275   
12276   new -> CFrogStr | |
12277    ^ ''
12278   
12279 
12280                                       Edit
12281   
12282   new | |
12283    ^ self basicNew
12284   
12285 
12286                                       Edit
12287   
12288   new | |
12289    ^ self basicNew
12290   
12291 
12292                                       Edit
12293   
12294   new | |
12295    ^ self basicNew init
12296   
12297 
12298                                       Edit
12299   
12300   new ->CFrogTime | |
12301    ^ self basicNew
12302 
12303                                       Edit
12304   
12305   new -> CFrogTongue | |
12306    ^ self basicNew init
12307   
12308 
12309                                       Edit
12310   
12311   new | |
12312    ^ self basicNew
12313   
12314 
12315                                       Edit
12316   
12317   new ->CGun1 | |
12318    ^ self basicNew init
12319   
12320 
12321                                       Edit
12322   
12323   new ->CGun1Pickup | |
12324    ^ self basicNew init
12325   
12326 
12327                                       Edit
12328   
12329   new ->CHandItem | |
12330    ^ self basicNew init
12331 
12332                                       Edit
12333   
12334   new | |
12335    ^ self basicNew init
12336   
12337 
12338                                       Edit
12339   
12340   new | |
12341    ^ self basicNew init
12342   
12343 
12344                                       Edit
12345   
12346   new | |
12347    ^ self basicNew init
12348   
12349 
12350                                       Edit
12351   
12352   new | |
12353    ^ self basicNew init
12354   
12355 
12356                                       Edit
12357   
12358   new | |
12359    ^ self basicNew init
12360   
12361 
12362                                       Edit
12363   
12364   new | |
12365    ^ self basicNew init
12366   
12367 
12368                                       Edit
12369   
12370   new | |
12371    ^ self basicNew init
12372   
12373 
12374                                       Edit
12375   
12376   new | |
12377    ^ self basicNew init
12378   
12379 
12380                                       Edit
12381   
12382   new | |
12383    ^ self basicNew init
12384   
12385 
12386                                       Edit
12387   
12388   new | |
12389    ^ self basicNew init
12390   
12391 
12392                                       Edit
12393   
12394   new | |
12395    ^ self basicNew init
12396   
12397 
12398                                       Edit
12399   
12400   new | |
12401    ^ self basicNew init
12402   
12403 
12404                                       Edit
12405   
12406   new ->CPickup | |
12407    ^ self basicNew init
12408   
12409 
12410                                       Edit
12411   
12412   new->CPissLink | |
12413    ^ self basicNew init
12414   
12415 
12416                                       Edit
12417   
12418   new ->CPissStream | |
12419    ^ self basicNew init
12420   
12421 
12422                                       Edit
12423   
12424   new->CPlayer | |
12425    ^ self basicNew init
12426   
12427 
12428                                       Edit
12429   
12430   new ->CPooka | |
12431    ^ self basicNew init
12432 
12433                                       Edit
12434   
12435   new->CPoopMan | |
12436    ^ self basicNew init
12437   
12438 
12439                                       Edit
12440   
12441   new | |
12442    ^ self basicNew init
12443   
12444 
12445                                       Edit
12446   
12447   new | |
12448    ^ self basicNew init
12449   
12450 
12451                                       Edit
12452   
12453   newWithTitle: title0=CFrogStr
12454     withImg: img0=CFrogStr
12455     withText: text0=CFrogStr
12456     withCategory: cat=CFrogStr
12457   ->*
12458   ||
12459    ^ self basicNew initWithTitle: title0 withImg: img0 withText: text0 
12460        withCategory: cat .
12461   
12462 
12463                                       Edit
12464   
12465   new | |
12466    ^ self basicNew init
12467   
12468 
12469                                       Edit
12470   
12471   new | |
12472    ^ self basicNew init
12473   
12474 
12475                                       Edit
12476   
12477   new | |
12478    ^ self basicNew init
12479 
12480                                       Edit
12481   
12482   new | |
12483    ^ self basicNew init
12484   
12485 
12486                                       Edit
12487   
12488   new | |
12489    ^ self basicNew init
12490 
12491                                       Edit
12492   
12493   new ->CShellCasing | |
12494    ^ self basicNew init
12495   
12496 
12497                                       Edit
12498   
12499   new | |
12500    ^ self basicNew init
12501   
12502 
12503                                       Edit
12504   
12505   new | |
12506    ^ self basicNew init
12507   
12508 
12509                                       Edit
12510   
12511   new ->CShootgun | |
12512    ^ self basicNew init
12513   
12514 
12515                                       Edit
12516   
12517   new ->CShootgunPickup | |
12518    ^ self basicNew init
12519 
12520                                       Edit
12521   
12522   new | |
12523    ^ self basicNew init
12524   
12525 
12526                                       Edit
12527   
12528   new | |
12529    ^ self basicNew init
12530   
12531 
12532                                       Edit
12533   
12534   new | |
12535    ^ self basicNew init
12536   
12537 
12538                                       Edit
12539   
12540   new | |
12541    ^ self basicNew init
12542   
12543 
12544                                       Edit
12545   
12546   new ->CTalker | |
12547    ^ self basicNew init 
12548 
12549                                       Edit
12550   
12551   new:t=C3DThing | |
12552    ^ self basicNew init: t
12553   
12554 
12555                                       Edit
12556   
12557   new | |
12558    ^ self basicNew init
12559   
12560 
12561                                       Edit
12562   
12563   new ->CUIBackground | |
12564    ^ self basicNew init
12565 
12566                                       Edit
12567   
12568   new ->CUIButton | |
12569    ^ self basicNew init
12570   
12571 
12572                                       Edit
12573   
12574   new ->CUICenter | |
12575    ^ self basicNew init
12576   
12577 
12578                                       Edit
12579   
12580   new ->CUIChatLog | |
12581    ^ self basicNew init
12582 
12583                                       Edit
12584   
12585   new ->CUIElem | |
12586    ^ self basicNew init
12587   
12588 
12589                                       Edit
12590   
12591   new | |
12592    ^ self basicNew init
12593   
12594 
12595                                       Edit
12596   
12597   new ->CUIGrid | |
12598    ^ self basicNew init
12599   
12600 
12601                                       Edit
12602   
12603   new ->CUIGridItem | |
12604    ^ self basicNew init
12605   
12606 
12607                                       Edit
12608   
12609   getItem ||
12610     ^ item 
12611 
12612                                       Edit
12613   
12614   new | |
12615    ^ self basicNew init
12616   
12617 
12618                                       Edit
12619   
12620   new ->CUILabel | |
12621    ^ self basicNew init
12622   
12623 
12624                                       Edit
12625   
12626   new | |
12627    ^ self basicNew init
12628   
12629 
12630                                       Edit
12631   
12632   new: pairs=CFrogArray ->CUIList
12633   |
12634   |
12635    ^ self basicNew init: pairs .
12636 
12637                                       Edit
12638   
12639   new ->CUIMeter | |
12640    ^ self basicNew init
12641 
12642                                       Edit
12643   
12644   new:msg=CFrogStr | |
12645    ^ self basicNew init: msg .
12646   
12647 
12648                                       Edit
12649   
12650   new ->CUIScrollBars | |
12651    ^ self basicNew init
12652   
12653 
12654                                       Edit
12655   
12656   new | |
12657    ^ self basicNew init
12658   
12659 
12660                                       Edit
12661   
12662   new ->CUITextBar | |
12663    ^ self basicNew init
12664   
12665 
12666                                       Edit
12667   
12668   new | |
12669    ^ self basicNew init
12670   
12671 
12672                                       Edit
12673   
12674   new | |
12675    ^ self basicNew init
12676   
12677 
12678                                       Edit
12679   
12680   new | |
12681    ^ self basicNew init
12682   
12683 
12684                                       Edit
12685   
12686   new | |
12687    ^ self basicNew init
12688   
12689 
12690                                       Edit
12691   
12692   new  ->CWallStain | |
12693    ^ self basicNew init
12694   
12695 
12696                                       Edit
12697   
12698   newStainAtX: x=CFrogNum atY: y=CFrogNum atZ: z=CFrogNum
12699     withGraphicsLump: lump=CFrogStr withSpread: sp=CFrogNum
12700     ->CWallStain
12701   |
12702     ws=CWallStain
12703     coords=CFrogArray
12704     stains=CFrogArray
12705     r=CFrogRandom
12706     sx=CFrogNum
12707     sy=CFrogNum
12708     placed*
12709   |
12710     ws _ CWallStain new .
12711     placed _ ws placeAtX: x atY: y atZ: z .
12712     (placed hasClass: CFrogNum) ifTrue: [
12713       ( placed ~= 0 ) ifTrue: [
12714         ws putGraphics: lump atX: ws->center_x + sx atY: ws->center_y + sy .
12715         ^ ws .
12716       ] .
12717     ].
12718     (placed hasClass: CDoor) ifTrue: [
12719       ws putGraphics: lump atX: ws->center_x + sx atY: ws->center_y + sy.
12720         ^ ws .
12721     ] .
12722     ^  0 
12723   
12724 
12725                                       Edit
12726   
12727   newStainAtX: x=CFrogNum atY: y=CFrogNum atZ: z=CFrogNum
12728     withGraphicsLump: lump=CFrogStr
12729     ->CWallStain
12730   |
12731   |
12732     ^ CWallStain newStainAtX: x atY: y atZ: z
12733       withGraphicsLump: lump withSpread: 0 . 
12734 
12735                                       Edit
12736   
12737   new | |
12738    ^ self basicNew init
12739   
12740 
12741                                       Edit
12742   
12743   new: block=CFrogNum -> * | |
12744    ^ self basicNew init: block 
12745   
12746 
12747                                       Edit
12748   
12749   new: name=CFrogStr | |
12750    ^ self basicNew init: name .
12751   
12752 
12753                                       Edit
12754   
12755   new ->CZombie | |
12756    ^ self basicNew init 
12757 
12758                                       Edit
12759   
12760   
12761 
12762 FrogChat
12763   
12764   #new_frog_conversation _ [:frognpc* |
12765     #frog1_chat _ CEliza makeResponsesFromArray: #(
12766       'Whatevers poppin,im hoppin'
12767       'where *' 'I live in a lily pad '
12768       '* work *' 'I sell meth for a living,I can also make your piss purple'
12769       '* buy *' #(
12770         'What are you buying'
12771         '* coadine *' #('It will turn your piss purple')
12772         '* ammo *' #('Time to flame it up')
12773       )
12774       '*' #(
12775          'Have you seen my lover'
12776          '* yes *' 'His name is Donald Trump'
12777          '* no *' #(
12778            'If you see him I have a quest for you'
12779          )
12780       )
12781       '* lover *' 'I may have cheated on Trump with a potato.'
12782       'who * lover *' 'Trump'
12783       '* Trump *' 'No cap I luv Donald Trump'
12784       '* Trump *' 'Trump needs hid twitter back so I cna thirst post to him'
12785       '*' 'I like food'
12786       '* food *'  #(
12787          'My favorite food is poop,DO NOT ask me more about this'
12788          '* poop *' #(
12789            'Heres the deal,I love shit,get me some shit and I have something for you'
12790          )
12791       )
12792       '*' #(
12793         'Have you tasted flies'
12794         '* yes *' 'They do taste good'
12795         '* no *' 'What the fuck is wrong with you?'
12796       )
12797       '* eat *' '(2) sounds yummy '
12798       '*' #(
12799         'What kind of music do you listen to'
12800         '* rap * ' 'I like 21 Savage and Drake and I fucking love Kanye'
12801         '* pop * ' 'Micheal Jackson is the king of pop'
12802         '* country * ' 'Tenesse hillbilies fucking there sisters for a good time?'
12803       )
12804       '* 21 *' '21 Savage is a fine rapper,21 Pussy 21' 
12805       '* Kanye *' 'Kanye West has a way with words,I like how his music is both directionless and meaningdful at the same time'
12806       '* Kanye *' 'Donda is a good album'
12807       '* Drake *' 'Drake is the king of rap but not pop music'
12808       '* Jackson *' #(
12809          'Micheal Jackson is a good singer,whats your favorite album of his?'
12810          '* Moonwalking *' 'Moon walking is a sick dance move'
12811          '* Bad *' 'Bad is the climax of the classic trillogy,I like Man in the mirror'
12812          '* Triller *' 'I used to listen to Thriller alot until "Gotta be startin somthin" got stuck in my head'
12813          '* Wall *' 'Off the wall is a classic'
12814          '* Dangerous *' 'Dangerous is a good album that embodies the staples of Micheal Jacksons music'
12815          '* Invincible *' 'Dogshit?'
12816       )
12817       '*' #(
12818         'How did you end up playing this game?'
12819         '* fun *' 'Sorry not much fun here'
12820         '* curious *' 'I dont even know why Im programming this garbage' 
12821         '* funny *' 'I know,peeing on people is funny right'
12822         '* dont* know *' 'I dont know either'
12823         '* not * sure *' 'Idk either bitch'
12824       )
12825     ) .
12826     #frog1_chat addSynonym: 'Ye' for: 'Kanye' .
12827     #frog1_chat addSynonym: 'favorite' for: 'best' .
12828     #frog1_chat addSynonym: 'curiosity' for: 'curious' .
12829     #frog1_chat addSynonym: 'moonwalking' for: 'moonwalk'
12830     #frog1_chat setQuit: 'Ribbit' .
12831     frognpc setChatBot: #frog1_chat .
12832     #frog1_chat
12833   ] .
12834